짬뽕얼큰하게의 맨땅에 헤딩 :: '분류 전체보기' 카테고리의 글 목록 (24 Page)

Water Bottles

알고리즘 2025. 2. 2. 20:46

summary

  • Maximum Water Bottles that can be drunk

approach

  • This solution uses a greedy approach, starting with the maximum possible number of full bottles and then repeatedly exchanging empty bottles for full ones until no more exchanges are possible.

complexity

  • O(n), where n is the number of full bottles

explain

  • The solution starts by adding the initial number of full bottles to the total count of water bottles that can be drunk
  • It then enters a loop where it repeatedly exchanges empty bottles for full ones until no more exchanges are possible
  • In each iteration of the loop, it calculates the number of full bottles that can be obtained from the available empty bottles and adds this to the total count
  • The number of full bottles that can be obtained in each iteration is calculated as the integer division of the number of available empty bottles by the exchange rate, plus the remainder of the division, which represents the number of empty bottles that are not enough to exchange for a full bottle.

Solution Code:


class Solution {
public:
    int numWaterBottles(int numBottles, int numExchange) {
        int ans = 0;
        ans += numBottles;
        while(numBottles >= numExchange){
            ans += numBottles/numExchange;
            numBottles = (numBottles/numExchange) + (numBottles % numExchange);
        }
        return ans;
    }
};

'알고리즘' 카테고리의 다른 글

Average Waiting Time  (0) 2025.02.02
Find the Winner of the Circular Game  (0) 2025.02.02
Pass the Pillow  (0) 2025.02.02
Find the Minimum and Maximum Number of Nodes Between Critical Points  (0) 2025.02.02
Merge Nodes in Between Zeros  (0) 2025.02.02
블로그 이미지

짬뽕얼큰하게

,

Pass the Pillow

알고리즘 2025. 2. 2. 20:43

summary

  • The problem is to find the index of the person holding the pillow after a given time in a line of people passing the pillow in both directions.

approach

  • The approach is to calculate the number of complete rounds the pillow makes and the remaining time, then determine the person holding the pillow based on the time.

complexity

  • O(1)

explain

  • The code first calculates the number of complete rounds the pillow makes by dividing the time by the number of people minus one
  • If the time is odd, the remaining time is the person holding the pillow, otherwise, it is the person after the remaining time
  • The code returns the index of the person holding the pillow.

Solution Code:


class Solution {
public:
    int passThePillow(int n, int time) {
        int a = time / (n-1);
        if(a&1){
            return n - time % (n-1);
        } else{
            return 1 + time % (n-1);
        }
    }
};
블로그 이미지

짬뽕얼큰하게

,

summary

  • Finding critical points in a linked list and calculating the minimum and maximum distances between them.

approach

  • The approach used is to traverse the linked list and keep track of the previous node's value
  • When a new node is encountered, it checks if the current node and the next node have the same value
  • If they do not, and the current node's value is greater than the previous node's value, or less than the previous node's value, it checks if the current node is a local maxima or minima
  • If it is, it adds the current index to the vector of nodes between critical points
  • The minimum distance is calculated by finding the minimum difference between any two indices in the vector, and the maximum distance is calculated by finding the maximum difference between any two indices in the vector.

complexity

  • O(n), where n is the number of nodes in the linked list

explain

  • The code first initializes a variable `prev` to -1 to keep track of the previous node's value
  • It then traverses the linked list, and for each node, it checks if the current node and the next node have the same value
  • If they do not, and the current node's value is greater than the previous node's value, or less than the previous node's value, it checks if the current node is a local maxima or minima
  • If it is, it adds the current index to the vector of nodes between critical points
  • The minimum distance is calculated by finding the minimum difference between any two indices in the vector, and the maximum distance is calculated by finding the maximum difference between any two indices in the vector
  • If there are fewer than two critical points, the function returns [-1, -1].

Solution Code:


/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    int prev = -1;
    vector nodesBetweenCriticalPoints(ListNode* head) {
        ListNode* ptr;
        vector ansVector;
        int minVal = 1234567890;
        int idx;
        for(ptr = head, idx=0; ptr->next != nullptr; ptr = ptr->next, idx++){
            if(prev == -1){
                prev = ptr->val;
                continue;
            }
            if (ptr->next->val > ptr->val && prev > ptr->val){
                if (!ansVector.empty()){
                    minVal = min(minVal, idx - ansVector.back());
                }
                ansVector.push_back(idx);
            } else if(ptr->next->val < ptr->val && prev < ptr->val){
                if (!ansVector.empty()){
                    minVal = min(minVal, idx - ansVector.back());
                }
                ansVector.push_back(idx);
            }
            prev = ptr->val;
        }
        if (ansVector.size() < 2) return {-1, -1};
        return {minVal, ansVector.back() - ansVector[0]};
    }
};

'알고리즘' 카테고리의 다른 글

Water Bottles  (0) 2025.02.02
Pass the Pillow  (0) 2025.02.02
Merge Nodes in Between Zeros  (0) 2025.02.02
Minimum Difference Between Largest and Smallest Value in Three Moves  (0) 2025.02.02
Intersection of Two Arrays II  (0) 2025.02.02
블로그 이미지

짬뽕얼큰하게

,

summary

  • Given a linked list containing integers separated by 0's, merge every two consecutive 0's into a single node whose value is the sum of all the merged nodes.

approach

  • This problem can be solved by iterating through the linked list and maintaining a running sum of nodes between two consecutive 0's
  • When a 0 is encountered, a new node is created with the sum of the nodes between the previous 0 and the current 0, and the sum is reset to 0.

complexity

  • O(n), where n is the number of nodes in the linked list, because each node is visited once.

explain

  • The solution code first initializes a pointer to the second node in the list (after the first node) and a pointer to the new node that will be created
  • It also initializes a sum variable to 0
  • Then, it iterates through the list, adding each node's value to the sum if the current node is not a 0
  • When a 0 is encountered, a new node is created with the sum of the nodes between the previous 0 and the current 0, and the sum is reset to 0
  • The new node is linked to the previous node, and the previous node becomes the current node
  • This process continues until the end of the list is reached, at which point the new node is returned as the head of the modified linked list.

Solution Code:


/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    
    ListNode* mergeNodes(ListNode* head) {
        ListNode* answer = nullptr;
        ListNode* ptr2;
        int sum = 0;
        for (ListNode* ptr = head-> next; ptr != nullptr; ptr = ptr->next){
            if(ptr->val == 0){
                if (answer == nullptr){
                    answer = new ListNode(sum);
                    ptr2 = answer;
                } else {
                    ptr2->next = new ListNode(sum);
                    ptr2 = ptr2->next;
                }
                sum = 0;
            } else {
                sum += ptr->val;
            }
        }
        return answer;
    }
};
블로그 이미지

짬뽕얼큰하게

,

summary

  • Find the minimum difference between the largest and smallest value of an integer array after performing at most three moves.

approach

  • This solution uses a depth-first search (DFS) approach to try all possible moves and find the minimum difference
  • The DFS function recursively tries different moves and updates the minimum difference
  • The main function first sorts the array and then calls the DFS function with the initial minimum and maximum values.

complexity

  • O(n * 4^3) where n is the number of elements in the array

explain

  • The solution starts by sorting the input array
  • Then, it uses a DFS function to try all possible moves
  • The DFS function takes the current array, the current depth (which represents the number of moves made so far), the left and right indices of the current subarray
  • If the current depth is 3, it means we have made 3 moves, so it returns the difference between the maximum and minimum values in the current subarray
  • Otherwise, it recursively tries two possible moves: moving the left element to the right and moving the right element to the left
  • The minimum difference found by these two recursive calls is returned
  • The main function calls the DFS function with the initial minimum and maximum values and returns the result.

Solution Code:


int abs(int x){
    return x < 0 ? -x : x;
}
class Solution {
public:
    int dfs(vector&nums, int depth, int l, int r){
        if (depth == 3){
            return nums[r] - nums[l];
        }
        int res = dfs(nums, depth+1, l+1, r);
        res = min(res, dfs(nums, depth+1, l, r-1));
        return res;
    }
    int minDifference(vector& nums) {
        if (nums.size() <= 3) return 0;
        sort(nums.begin(), nums.end());
        int l = 0;
        int r = nums.size() - 1;
        return dfs(nums, 0, l, r);
    }
};
블로그 이미지

짬뽕얼큰하게

,

summary

  • Given two integer arrays, return an array of their intersection
  • Each element in the result must appear as many times as it shows in both arrays.

approach

  • The approach used is to first count the occurrences of each element in the first array using an unordered map
  • Then, for each element in the second array, if it exists in the map and its count is greater than 0, decrement the count and add the element to the result array.

complexity

  • O(n + m) where n and m are the sizes of the input arrays

explain

  • The solution iterates over the first array to count the occurrences of each element in the unordered map
  • Then, it iterates over the second array to find elements that exist in the map and add them to the result array
  • This approach ensures that each element in the result appears as many times as it shows in both arrays.

Solution Code:


class Solution {
public:
    vector intersect(vector& nums1, vector& nums2) {
        vector answer;
        unordered_map cnt;
        for(int i = 0 ; i < nums1.size(); i++){
            cnt[nums1[i]]++;
        }
        for(int i = 0 ; i < nums2.size(); i++){
            if(cnt[nums2[i]]){
                cnt[nums2[i]]--;
                answer.push_back(nums2[i]);
            }
        }
        return answer;
    }
};
블로그 이미지

짬뽕얼큰하게

,

summary

  • Given an integer array, return true if there are three consecutive odd numbers in the array, otherwise return false.

approach

  • The solution uses a counter to keep track of the number of consecutive odd numbers
  • It iterates over the array, incrementing the counter whenever it encounters an odd number and resetting it whenever it encounters an even number
  • If the counter reaches 3, it immediately returns true
  • If it iterates over the entire array without finding three consecutive odd numbers, it returns false.

complexity

  • O(n) where n is the number of elements in the array

explain

  • The solution has a time complexity of O(n) because it makes a single pass over the array
  • The space complexity is O(1) because it uses a constant amount of space to store the counter.

Solution Code:


class Solution {
public:
    bool threeConsecutiveOdds(vector& arr) {
        int cnt = 0;
        for(int i = 0 ; i < arr.size(); i++){
            if(arr[i] & 1){
                cnt++;
            } else {
                cnt = 0;
            }
            if (cnt >= 3) return true;
        }
        return false;
    }
};
블로그 이미지

짬뽕얼큰하게

,

summary

  • This problem involves finding the maximum number of edges that can be removed from an undirected graph so that it can still be fully traversed by both Alice and Bob.

approach

  • The approach used in this solution is to first separate the edges into three types: Type 1 (can be traversed by Alice only), Type 2 (can be traversed by Bob only), and Type 3 (can be traversed by both Alice and Bob)
  • Then, we use disjoint sets to keep track of the connected components of the graph for each type of edge
  • We remove the maximum number of edges of Type 3 while ensuring that the graph remains fully traversable by both Alice and Bob.

complexity

  • O(n log n + m log m + n log n) where n is the number of nodes and m is the number of edges

explain

  • The solution starts by separating the edges into three types and initializing two disjoint sets for Alice and Bob
  • It then sorts the edges of each type by their type and uses the disjoint sets to keep track of the connected components of the graph
  • The solution then removes the maximum number of edges of Type 3 while ensuring that the graph remains fully traversable by both Alice and Bob
  • If the graph is not fully traversable, the solution returns -1
  • The time complexity is O(n log n + m log m + n log n) due to the sorting and disjoint set operations.

Solution Code:




class Solution {
public:
    int u1[100001];
    int u2[100001];
    
    vector> edgesType1;
    vector> edgesType2;
    static bool cmp1(vector &a, vector &b){
        return a[0] > b[0];
    }
    static bool cmp2(vector &a, vector &b){
        return a[0] > b[0];
    }
    int disjoint(int* u, int x){
        if(u[x] == x) return x;
        return u[x] = disjoint(u, u[x]);
    }
    int maxNumEdgesToRemove(int n, vector>& edges) {
        edgesType1.clear();
        edgesType2.clear();
        int edgeSize = edges.size();
        for(int i = 1; i <= n; i++){
            u1[i] = i;
            u2[i] = i;
        }
        for(int i = 0; i < edges.size(); i++){
            if(edges[i][0] == 1){
                edgesType1.push_back(edges[i]);
            } else if (edges[i][0] == 2){
                edgesType2.push_back(edges[i]);
            } else{
                edgesType1.push_back(edges[i]);
                edgesType2.push_back(edges[i]);
            }
        }
        sort(edgesType1.begin(), edgesType1.end(), cmp1);
        sort(edgesType2.begin(), edgesType2.end(), cmp2);

        int type3 = 0;
        int cnt = 0;
        for (int idx = 0 ; idx < edgesType1.size(); idx++) {
            int type = edgesType1[idx][0];
            int a = edgesType1[idx][1];
            int b = edgesType1[idx][2];
            if(disjoint(u1, a) == disjoint(u1, b)){
                continue;
            }
            cnt++; 
            u1[disjoint(u1, a)] = disjoint(u1, b);
            if (type == 3){
                type3 += 1;
            }
            if (cnt == n -1) break;
        }
        if (cnt != n-1) return -1;
        cnt = 0;
        for (int idx = 0 ; idx < edgesType2.size(); idx++) {
            int type = edgesType2[idx][0];
            int a = edgesType2[idx][1];
            int b = edgesType2[idx][2];
            if(disjoint(u2, a) == disjoint(u2, b)){
                continue;
            }
            cnt++; 
            u2[disjoint(u2, a)] = disjoint(u2, b);
            if (cnt == n -1) break;
        }
        if (cnt != n-1) return -1;

        return edges.size() - (n - 1) - (n - 1) + type3;
    }
};

'알고리즘' 카테고리의 다른 글

Intersection of Two Arrays II  (0) 2025.02.02
Three Consecutive Odds  (0) 2025.02.02
Find Center of Star Graph  (0) 2025.02.02
Longest Continuous Subarray With Absolute Diff Less Than or Equal to Limit  (0) 2025.02.02
Special Array I  (0) 2025.02.02
블로그 이미지

짬뽕얼큰하게

,

summary

  • Finding the Center of a Star Graph

approach

  • The solution iterates over each edge in the graph and increments the count of the nodes at each end of the edge
  • It then checks if the count of any node exceeds 1
  • If so, that node is the center of the star graph and the function returns it.

complexity

  • O(n)

explain

  • The time complexity of this solution is O(n) because in the worst case, we might have to iterate over all n edges
  • The space complexity is also O(n) because in the worst case, we might have to store the count of all n nodes.

Solution Code:


class Solution {
public:
    int findCenter(vector>& edges) {
        int cnt[100001] = {0};
        for(int i = 0 ; i < edges.size(); i++){
            int a = edges[i][0];
            int b = edges[i][1];
            cnt[a]++;
            cnt[b]++;
            if (cnt[a] >= 2) return a;
            if (cnt[b] >= 2) return b;
        }
        return 0;
    }
};
블로그 이미지

짬뽕얼큰하게

,

summary

  • The problem is to find the size of the longest non-empty subarray in the given array of integers such that the absolute difference between any two elements of this subarray is less than or equal to the given limit.

approach

  • The approach used is to use a sliding window technique with a multiset data structure to store the elements of the subarray
  • The multiset is used to keep track of the minimum and maximum elements in the current subarray
  • The sliding window is expanded to the right by adding elements to the multiset and contracting the window from the left by removing elements from the multiset if the absolute difference between the minimum and maximum elements exceeds the limit.

complexity

  • O(N log N) due to the insertion and removal operations in the multiset, where N is the size of the input array.

explain

  • The solution code initializes two pointers, l and r, to the start of the array
  • It also initializes a multiset, multi, to store the elements of the subarray
  • The code then enters a loop where it expands the sliding window to the right by adding elements to the multiset and checking if the absolute difference between the minimum and maximum elements exceeds the limit
  • If it does, the code contracts the window from the left by removing elements from the multiset
  • The code keeps track of the maximum length of the subarray seen so far and returns it at the end.

Solution Code:


class Solution {
public:
    int longestSubarray(vector& nums, int limit) {
        int l = 0;
        int r = 0;
        multiset multi;
        int N = nums.size();
        int ans = 0;
        
        multi.insert(nums[0]);
        while(r < N){
            int last = *(multi.rbegin());
            int first = *(multi.begin());
            if (abs(last - first) <= limit){
                ans = max(ans, r-l+1);
                r++;
                if (r < N){
                    multi.insert(nums[r]);
                }
            } else{
                multi.erase(multi.find(nums[l]));
                l++;
            }
        }
        return ans;
    }
};

'알고리즘' 카테고리의 다른 글

Remove Max Number of Edges to Keep Graph Fully Traversable  (0) 2025.02.02
Find Center of Star Graph  (0) 2025.02.02
Special Array I  (0) 2025.02.02
Check if Array Is Sorted and Rotated  (0) 2025.02.02
Making A Large Island  (0) 2025.02.02
블로그 이미지

짬뽕얼큰하게

,