koenjazh-CNfresde
짬뽕얼큰하게의 맨땅에 헤딩 :: '2025/02/02 글 목록

Leetcode Problem:

Summary

  • Given a string s and two integers x and y, find the maximum points that can be gained by removing substrings of 'ab' and 'ba' from s.

Approach

  • The solution uses a two-step approach
  • First, it removes all occurrences of 'ab' or 'ba' from the string s, depending on which one has a higher value
  • Then, it removes the remaining 'ab' or 'ba' substrings from the resulting string
  • The points gained for each step are added to the total score.

Complexity

  • O(n), where n is the length of the string s
  • This is because the solution makes two passes through the string s, one for each step.

Explain

  • The solution starts by initializing two vectors, firstStep and secondStep, to store the characters of the string s after the first and second steps, respectively
  • It also initializes the total score res to 0
  • The solution then iterates over the string s, adding characters to firstStep and secondStep based on whether they are 'ab' or 'ba'
  • If a character is 'ab' or 'ba', the solution checks if the last character in the vector is the same as the character in 'ab' or 'ba'
  • If they are the same, the solution adds the points gained for the step to the total score and removes the character from the vector
  • Otherwise, the solution adds the character to the vector
  • Finally, the solution returns the total score.

Solution Code:


class Solution {
public:
    int maximumGain(string s, int x, int y) {
        int res = 0;
        vector firstStep;
        string cmpStr;
        int maxScore = max(x, y);
        int minScore = min(x, y);
        if (x > y){
            cmpStr = "ab";
        } else {
            cmpStr = "ba";
        }

        for(int i = 0 ; i < s.size(); i++){
            if (firstStep.size() == 0 || s[i] != cmpStr[1]){
                firstStep.push_back(s[i]);
            } else {
                char c = firstStep.back();
                if (c == cmpStr[0]){
                    res += maxScore;
                    firstStep.pop_back();
                } else {
                    firstStep.push_back(s[i]);
                }
            }
        }
        vector secondStep;

        for(int i = 0 ; i < firstStep.size(); i++){
            if (secondStep.size() == 0 || firstStep[i] != cmpStr[0]){
                secondStep.push_back(firstStep[i]);
            } else {
                char c = secondStep.back();
                if (c == cmpStr[1]){
                    res += minScore;
                    secondStep.pop_back();
                }else {
                    secondStep.push_back(firstStep[i]);
                }
            }
        }
        return res;
    }
};
블로그 이미지

짬뽕얼큰하게

,

summary

  • Given a string s that consists of lower case English letters and brackets, reverse the strings in each pair of matching parentheses, starting from the innermost one.

approach

  • This solution uses a stack to keep track of the indices of the characters that need to be reversed
  • When a closing parenthesis is encountered, the solution pops the corresponding opening parenthesis index from the stack, reverses the substring between these two indices, and then removes the opening parenthesis from the stack.

complexity

  • O(N)

explain

  • The solution iterates over the string s
  • When it encounters an opening parenthesis, it pushes the current length of the string onto the stack
  • When it encounters a closing parenthesis, it pops the corresponding opening parenthesis index from the stack, reverses the substring between these two indices, and then removes the opening parenthesis from the stack
  • The solution continues this process until it has processed the entire string.

Solution Code:


class Solution {
public:
    
    string reverseParentheses(string s) {
        string res = "";
        int mystack[2001];
        int stackIdx = 0;
        int N = s.length();
        int idx = 0;
        for(int i = 0 ; i < N; i++){
            if (s[i] == '('){
                mystack[stackIdx++] = res.length();
            } else if (s[i] == ')'){
                int popIdx = mystack[--stackIdx];
                reverse(res.begin()+popIdx, res.end());
            } else {
                res += s[i];
            }
        }
        return res;
    }
};

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

Create Binary Tree From Descriptions  (0) 2025.02.03
Maximum Score From Removing Substrings  (0) 2025.02.02
Crawler Log Folder  (0) 2025.02.02
Average Waiting Time  (0) 2025.02.02
Find the Winner of the Circular Game  (0) 2025.02.02
블로그 이미지

짬뽕얼큰하게

,

Crawler Log Folder

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

summary

  • The problem is to find the minimum number of operations needed to go back to the main folder after a series of change folder operations.

approach

  • The solution uses a stack data structure to keep track of the current folder path
  • When a folder operation is encountered, the corresponding action is performed on the stack
  • If the operation is '../', the top element is removed from the stack
  • If the operation is './', the top element is left unchanged
  • If the operation is 'x/', the top element is replaced with 'x'
  • The minimum number of operations needed to go back to the main folder is the number of times '../' is performed minus the number of times './' is performed.

complexity

  • O(n), where n is the number of operations in the logs array

explain

  • The solution iterates over the logs array and performs the corresponding action on the stack for each operation
  • The stack is used to keep track of the current folder path
  • When the stack is empty and an '../' operation is encountered, the solution returns 0
  • Otherwise, the solution returns the difference between the number of '../' operations and the number of './' operations.

Solution Code:


class Solution {
public:
    int minOperations(vector& logs) {
        int cnt = 0;
        for(int i = 0; i < logs.size(); i++){
            if(!logs[i].compare("../")){
                cnt = cnt - 1 < 0 ? 0 : cnt - 1;
            } else if (!logs[i].compare("./")){

            } else {
                cnt++;
            }
        }
        return cnt;
    }
};

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

Maximum Score From Removing Substrings  (0) 2025.02.02
Reverse Substrings Between Each Pair of Parentheses  (0) 2025.02.02
Average Waiting Time  (0) 2025.02.02
Find the Winner of the Circular Game  (0) 2025.02.02
Water Bottles  (0) 2025.02.02
블로그 이미지

짬뽕얼큰하게

,

summary

  • Calculate the average waiting time of customers in a restaurant.

approach

  • This solution uses a greedy approach to calculate the average waiting time of customers
  • It iterates over the customers and calculates the waiting time for each customer based on the time the chef is idle
  • The total waiting time is then divided by the number of customers to get the average waiting time.

complexity

  • O(n)

explain

  • The solution works by iterating over the customers and calculating the waiting time for each customer
  • If the customer arrives after the chef is idle, the waiting time is the time the chef has been idle plus the preparation time
  • If the customer arrives before the chef is idle, the waiting time is the time the chef has been idle plus the preparation time minus the time the customer arrived
  • The total waiting time is then divided by the number of customers to get the average waiting time.

Solution Code:


class Solution {
public:
    double averageWaitingTime(vector>& customers) {
        long long totalWait = 0;
        long long time = 0;
        for(int i = 0 ; i < customers.size(); i++){
            int arrival = customers[i][0];
            int prepareTime = customers[i][1];

            if (arrival > time){
                time = arrival + prepareTime;
                totalWait += prepareTime;
            } else {
                totalWait += time - arrival + prepareTime;
                time += prepareTime;
            }
        }
        return (double)totalWait / customers.size();
    }
};

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

Reverse Substrings Between Each Pair of Parentheses  (0) 2025.02.02
Crawler Log Folder  (0) 2025.02.02
Find the Winner of the Circular Game  (0) 2025.02.02
Water Bottles  (0) 2025.02.02
Pass the Pillow  (0) 2025.02.02
블로그 이미지

짬뽕얼큰하게

,

summary

  • The problem is a game where n friends are sitting in a circle and the winner is determined by counting k friends in the clockwise direction, including the starting friend
  • The last friend counted leaves the circle and loses the game.

approach

  • The approach used in the solution code is to simulate the game by inserting the friends into a circular linked list and then repeatedly removing the last k friends from the list until only one friend is left
  • The last remaining friend is the winner.

complexity

  • The time complexity of the solution code is O(n * k), where n is the number of friends and k is the number of friends to count
  • This is because the code inserts each friend into the list once and then repeatedly removes the last k friends from the list until only one friend is left.

explain

  • The solution code first inserts all n friends into a circular linked list using the `insertLast` method
  • Then, it repeatedly removes the last k friends from the list using the `removeK` method until only one friend is left
  • The last remaining friend is the winner, which is returned by the `findTheWinner` method.

Solution Code:


struct node{
    int val;
    struct node *next;
    struct node *prev;
    node(){
        val = -1;
        next = this;
        prev = this;
    }
};




class Solution {
public:
    node head;
    
    void insertLast(int v){
        node* newNode = new node();
        newNode->val = v;
        newNode->prev = head.prev;
        newNode->next = &head;
        head.prev->next = newNode;
        head.prev = newNode;
    }
    node* removeK(node* ptr, int k){
        for(int i = 0 ; i < k; i++){
            if(ptr->next == &head){
                ptr = ptr->next;
            }
            ptr = ptr->next;
        }
        if (ptr->next == &head){
            ptr = ptr->next;
        }
        node* deleteNode = ptr->next;
        ptr->next = deleteNode->next;
        deleteNode->next->prev = ptr;
        // delete deleteNode;
        return ptr;
    }

    int findTheWinner(int n, int k) {
        for(int i = 1; i <= n; i++){
            insertLast(i);
        }
        node* ptr = &head;
        while(n-- > 1){
            ptr = removeK(ptr, k-1);
            cout << ptr->next->val << endl;
        }
        return head.next->val;
    }
};

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

Crawler Log Folder  (0) 2025.02.02
Average Waiting Time  (0) 2025.02.02
Water Bottles  (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
블로그 이미지

짬뽕얼큰하게

,

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);
    }
};
블로그 이미지

짬뽕얼큰하게

,