짬뽕얼큰하게의 맨땅에 헤딩 :: '알고리즘' 카테고리의 글 목록 (19 Page)

Design Circular Deque

알고리즘 2025. 2. 13. 08:48

Leetcode Problem:

Summary

  • Design a circular double-ended queue (deque) with methods to insert elements at the front and rear, delete elements from the front and rear, and check if the queue is empty or full.

Approach

  • A circular deque is implemented using a fixed-size array
  • The front and rear indices are used to track the current positions of the front and rear elements
  • The insertFront, insertLast, deleteFront, and deleteLast methods update the front and rear indices accordingly
  • The isEmpty and isFull methods check the front and rear indices to determine if the queue is empty or full.

Complexity

  • O(1) for insertFront, insertLast, deleteFront, deleteLast, getFront, getRear, isEmpty, and isFull operations
  • O(n) for printing the queue, where n is the number of elements in the queue.

Explain

  • The MyCircularDeque class is implemented using a fixed-size array of size k+2
  • The front and rear indices are used to track the current positions of the front and rear elements
  • The insertFront method adds an element at the front of the queue and updates the front index
  • The insertLast method adds an element at the rear of the queue and updates the rear index
  • The deleteFront method removes an element from the front of the queue and updates the front index
  • The deleteLast method removes an element from the rear of the queue and updates the rear index
  • The getFront and getRear methods return the front and rear elements respectively
  • The isEmpty and isFull methods check if the queue is empty or full by comparing the front and rear indices.

Solution Code:


class MyCircularDeque {
public:
    int deque[1001];
    int size;
    int front;
    int rear;
    
    MyCircularDeque(int k) {
        size = k+2;
        front = rear = 0;
    }
    
    bool insertFront(int value) {
        if (isFull()) return false;
        if (isEmpty()){
            rear++;
            rear %= size;
        }
        deque[front--] = value;
        front = (front + size) % size;
        return true;
    }
    
    bool insertLast(int value) {
        if (isFull()) return false;
        if (isEmpty()){
            front = (front-1 + size) % size;
        }
        deque[rear++] = value;
        rear %= size;
        return true;
    }
    
    bool deleteFront() {
        if (isEmpty()) return false;
        front = (front + 1)%size;
        if ((front + 1)%size == rear){
            rear = front;
        }
        
        return true;
    }
    
    bool deleteLast() {
        if (isEmpty()) return false;
        rear = (rear - 1 + size) % size;
        if ((rear - 1 + size)%size == front){
            front = rear;
        }
        return true;
    }
    
    int getFront() {
        if (isEmpty()) return -1;
        int getIdx = (front + 1) % size;
        return deque[getIdx];
    }
    
    int getRear() {
        if (isEmpty()) return -1;
        int getIdx = (rear - 1 + size) % size;
        return deque[getIdx];
    }
    
    bool isEmpty() {
        return front == rear;
    }
    
    bool isFull() {
        return front == (rear + 1) % size;
    }
};

/**
 * Your MyCircularDeque object will be instantiated and called as such:
 * MyCircularDeque* obj = new MyCircularDeque(k);
 * bool param_1 = obj->insertFront(value);
 * bool param_2 = obj->insertLast(value);
 * bool param_3 = obj->deleteFront();
 * bool param_4 = obj->deleteLast();
 * int param_5 = obj->getFront();
 * int param_6 = obj->getRear();
 * bool param_7 = obj->isEmpty();
 * bool param_8 = obj->isFull();
 */

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

Design a Stack With Increment Operation  (0) 2025.02.13
All O`one Data Structure  (0) 2025.02.13
My Calendar II  (0) 2025.02.13
My Calendar I  (0) 2025.02.13
Sum of Prefix Scores of Strings  (0) 2025.02.13
블로그 이미지

짬뽕얼큰하게

,

My Calendar II

알고리즘 2025. 2. 13. 08:44

Leetcode Problem:

Summary

  • Implementing a calendar system to avoid triple booking.

Approach

  • This solution uses a data structure to store the events in the calendar
  • It first checks for overlapping events with existing events in the calendar and returns false if a triple booking is found
  • If no overlap is found, it adds the new event to the calendar.

Complexity

  • O(n log n) due to sorting of events in the calendar

Explain

  • The MyCalendarTwo class uses a vector to store the events in the calendar
  • The book method first checks for overlapping events with existing events in the calendar
  • It uses a nested loop to check for overlapping events and returns false if a triple booking is found
  • If no overlap is found, it adds the new event to the calendar
  • The time complexity of this solution is O(n log n) due to sorting of events in the calendar.

Solution Code:


struct _pair{
    int start;
    int end;
};
class MyCalendarTwo {
public:
    vector<_pair> bookList;
    MyCalendarTwo() {
        
    }
    
    bool book(int start, int end) {
        vector<_pair> doubleBookList;
        for(_pair book : bookList){
            if(book.start >= end || book.end <= start){
                continue;
            }
            int s = max(book.start, start);
            int e = min(book.end, end);
            for(_pair db: doubleBookList){
                if(db.start >= e || db.end <= s){
                    continue;
                }
                return false;
            }
            doubleBookList.push_back({s, e});
        }
        bookList.push_back({start, end});
        return true;
    }
};

/**
 * Your MyCalendarTwo object will be instantiated and called as such:
 * MyCalendarTwo* obj = new MyCalendarTwo();
 * bool param_1 = obj->book(start,end);
 */

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

All O`one Data Structure  (0) 2025.02.13
Design Circular Deque  (0) 2025.02.13
My Calendar I  (0) 2025.02.13
Sum of Prefix Scores of Strings  (0) 2025.02.13
Max Sum of a Pair With Equal Sum of Digits  (0) 2025.02.12
블로그 이미지

짬뽕얼큰하게

,

My Calendar I

알고리즘 2025. 2. 13. 08:40

Leetcode Problem:

Summary

  • Implementing a program to use as a calendar to avoid double booking.

Approach

  • We use a vector of pairs to store the events in the calendar
  • For each new event, we check if it intersects with any existing events
  • If it does, we return false
  • Otherwise, we add the new event to the calendar.

Complexity

  • O(n) where n is the number of events in the calendar

Explain

  • We define a struct _pair to store the start and end times of each event
  • In the book function, we iterate over each event in the calendar
  • If the end time of the new event is less than or equal to the start time of an existing event, or if the start time of the new event is greater than the end time of an existing event, we continue to the next event
  • If we find an existing event that intersects with the new event, we return false
  • Otherwise, we add the new event to the calendar by pushing it onto the vector of pairs and return true.

Solution Code:


struct _pair{
    int start;
    int end;
};
class MyCalendar {
public:
    vector<_pair> v;
    MyCalendar() {
        
    }
    
    bool book(int start, int end) {
        for(_pair p : v){
            if (end <= p.start || p.end <= start){
                continue;
            }
            return false;
        }
        v.push_back({start, end});
        return true;
    }
};

/**
 * Your MyCalendar object will be instantiated and called as such:
 * MyCalendar* obj = new MyCalendar();
 * bool param_1 = obj->book(start,end);
 */

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

Design Circular Deque  (0) 2025.02.13
My Calendar II  (0) 2025.02.13
Sum of Prefix Scores of Strings  (0) 2025.02.13
Max Sum of a Pair With Equal Sum of Digits  (0) 2025.02.12
Find the Length of the Longest Common Prefix  (0) 2025.02.12
블로그 이미지

짬뽕얼큰하게

,

Leetcode Problem:

Summary

  • Given an array of strings, the problem requires finding the sum of scores of every non-empty prefix of each string
  • The score of a string is the number of strings that it is a prefix of.

Approach

  • A Trie data structure is used to store the given words
  • Each node in the Trie represents a character in the word
  • The score of each node is the number of words that it is a prefix of
  • The insert function is used to insert words into the Trie, and the getScore function is used to calculate the score of a given word.

Complexity

  • O(n * m * 26) where n is the number of words and m is the maximum length of a word
  • This is because in the worst case, we need to traverse the Trie for each word and for each character in the word.

Explain

  • The insert function is used to insert words into the Trie
  • It starts from the root node and traverses the Trie based on the characters in the word
  • The score of each node is incremented whenever a word is inserted
  • The getScore function is used to calculate the score of a given word
  • It starts from the root node and traverses the Trie based on the characters in the word, adding the score of each node to the total score.

Solution Code:


struct trie{
    int score;
    trie* next[26];
    bool tail;
    trie(){
        score = 0;
        for(int i = 0 ; i < 26; i++){
            next[i] = nullptr;
        }
        tail = false;
    }
    ~trie(){
        for(int i = 0 ; i < 26; i++){
            if(next[i] != nullptr) delete next[i];
            next[i] = nullptr;
        }
    }
};

void insert(trie* root, string &s, int s_idx, int size){
    if (s_idx == size) {
        root->tail = true;
        return;
    }
    int idx = s[s_idx]-'a';
    if(root->next[idx] == nullptr){
        root->next[idx] = new trie();
    }
    root->next[idx]->score++;
    insert(root->next[idx], s, s_idx+1, size);
}
int getScore(trie* root, string &s, int s_idx, int size){
    if(s_idx == size) return root->score;
    int idx = s[s_idx] - 'a';
    return root->score + getScore(root->next[idx], s, s_idx + 1, size);
}

class Solution {
public:
    vector sumPrefixScores(vector& words) {
        trie t;
        vector ans;
        for(string word : words){
            insert(&t, word, 0, word.size());
        }
        for(string word : words){
            int score = getScore(&t, word, 0, word.size());
            ans.push_back(score);
        }
        return ans;
    }
};

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

My Calendar II  (0) 2025.02.13
My Calendar I  (0) 2025.02.13
Max Sum of a Pair With Equal Sum of Digits  (0) 2025.02.12
Find the Length of the Longest Common Prefix  (0) 2025.02.12
Extra Characters in a String  (0) 2025.02.12
블로그 이미지

짬뽕얼큰하게

,

Leetcode Problem:

Summary

  • Find the maximum sum of two numbers in an array where the sum of digits of each number is equal.

Approach

  • The approach used is to calculate the sum of digits of each number and store them in a map
  • Then, for each sum of digits, find the two numbers in the map that can be added together to get the maximum sum
  • If there are multiple pairs, choose the one with the maximum sum.

Complexity

  • O(n log n) due to the sorting of the numbers in the map

Explain

  • The code first calculates the sum of digits of each number using the digit_sum function
  • Then, it stores these sums and their corresponding numbers in a map
  • For each sum of digits, it checks if there are already two numbers in the map that can be added together to get a larger sum
  • If not, it adds the current number to the map and updates the map if the current number is larger than the one already in the map
  • Finally, it iterates over the map to find the maximum sum of two numbers that can be obtained.

Solution Code:


class Solution {
public:
    unordered_map> map;
    int digit_sum(int num){
        int s = 0;
        while(num){
            s += num % 10;
            num /= 10;
        }
        return s;
    }
    int maximumSum(vector& nums) {
        for(int i = 0 ; i < nums.size(); i++){
            int digit = digit_sum(nums[i]);
            if(map[digit].size() < 2){
                map[digit].push_back(nums[i]);
                if(map[digit].size() == 2 && map[digit][0] < map[digit][1]){
                    int t = map[digit][0];
                    map[digit][0] = map[digit][1];
                    map[digit][1] = t;
                }
            } else{
                if(map[digit][0] <= nums[i]){
                    map[digit][1] = map[digit][0];
                    map[digit][0] = nums[i];
                } else{
                    map[digit][1] = max(map[digit][1], nums[i]);
                }
            }
        }
        int ans = -1;
        for(auto iter: map){
            if((iter.second).size() == 2){
                if(ans < (iter.second[0] + iter.second[1])){
                    ans = iter.second[0] + iter.second[1];
                }
            }
        }
        return ans;
    }
};

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

My Calendar I  (0) 2025.02.13
Sum of Prefix Scores of Strings  (0) 2025.02.13
Find the Length of the Longest Common Prefix  (0) 2025.02.12
Extra Characters in a String  (0) 2025.02.12
K-th Smallest in Lexicographical Order  (0) 2025.02.12
블로그 이미지

짬뽕얼큰하게

,

Leetcode Problem:

Summary

  • Find the length of the longest common prefix among all pairs of integers (x, y) such that x belongs to arr1 and y belongs to arr2.

Approach

  • Use a set to store the digits of the numbers in arr1 and then for each number in arr2, check if the digits are present in the set
  • If they are, update the answer with the maximum count of digits found so far.

Complexity

  • O(n*m*log(max(arr1[i], arr2[i]))) where n is the size of arr1 and m is the size of arr2

Explain

  • The time complexity of this solution is O(n*m*log(max(arr1[i], arr2[i]))) because for each number in arr1, we are inserting its digits into the set, and for each number in arr2, we are checking if its digits are present in the set
  • The space complexity is O(n*m) because we are storing all the digits in the set.

Solution Code:


class Solution {
public:
    set s;
    int getCount(int a){
        int cnt = 0;
        while(a){
            cnt++;
            a /= 10;
        }
        return cnt;
    }
    int longestCommonPrefix(vector& arr1, vector& arr2) {
        int ans = 0;
        for(int i = 0 ; i < arr1.size(); i++){
            while(arr1[i]){
                s.insert(arr1[i]);
                arr1[i] /= 10;
            }
        }
        for(int i = 0 ; i < arr2.size(); i++){
            while(arr2[i]){
                if (s.find(arr2[i]) != s.end()){
                    ans = max(ans, getCount(arr2[i]));
                    break;
                }
                arr2[i] /= 10;
            }
        }
        return ans;
    }
};

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

Sum of Prefix Scores of Strings  (0) 2025.02.13
Max Sum of a Pair With Equal Sum of Digits  (0) 2025.02.12
Extra Characters in a String  (0) 2025.02.12
K-th Smallest in Lexicographical Order  (0) 2025.02.12
Largest Number  (0) 2025.02.12
블로그 이미지

짬뽕얼큰하게

,

Leetcode Problem:

Summary

  • Given a string s and a dictionary of words, find the minimum number of extra characters left over if the string is broken into non-overlapping substrings present in the dictionary.

Approach

  • Dynamic programming approach, where a 1D array dp is used to store the minimum number of extra characters for each prefix of the string
  • The function go recursively tries to match the current prefix with each word in the dictionary, and updates the dp array accordingly.

Complexity

  • O(n*m*len(word)) where n is the length of the string, m is the number of words in the dictionary, and len(word) is the length of each word in the dictionary.

Explain

  • The function go takes a string s, a dictionary of words dict, and an integer i as input
  • It first checks if the current prefix of the string has been processed before (i.e., dp[i] is not -1)
  • If not, it sets dp[i] to 1 (for the extra character) and recursively calls itself for the next character
  • Then it tries to match the current prefix with each word in the dictionary, and updates dp[i] with the minimum of its current value and the result of the recursive call for the next character plus the length of the current word
  • The function minExtraChar initializes the dp array and calls the function go with the initial prefix as an empty string.

Solution Code:


class Solution {
public:
    int dp[51];
    int go(string & s, vector& dict, int i){
        if(i == s.size()) return 0;

        if (dp[i] == -1){
            dp[i] = 1 + go(s, dict, i+1);
            for(auto &w: dict){
                if(s.compare(i, w.size(), w) == 0){
                    dp[i] = min(dp[i], go(s, dict, i+w.size()));
                }
            }
        }
        return dp[i];

    }
    int minExtraChar(string s, vector& dictionary) {
        memset(dp, -1, sizeof(dp));
        return go(s, dictionary, 0);
    }
};

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

Max Sum of a Pair With Equal Sum of Digits  (0) 2025.02.12
Find the Length of the Longest Common Prefix  (0) 2025.02.12
K-th Smallest in Lexicographical Order  (0) 2025.02.12
Largest Number  (0) 2025.02.12
XOR Queries of a Subarray  (0) 2025.02.12
블로그 이미지

짬뽕얼큰하게

,

Leetcode Problem:

Summary

  • Given two integers n and k, return the kth lexicographically smallest integer in the range [1, n].

Approach

  • The solution uses a binary search approach to find the kth lexicographically smallest number
  • It first calculates the number of numbers less than or equal to n that can be formed by appending a digit from 1 to 9 to the current number
  • Then it recursively finds the kth lexicographically smallest number by finding the kth number that can be formed by appending a digit from 1 to 9 to the current number.

Complexity

  • O(log(n))

Explain

  • The solution consists of two main functions: findKthNumber and findKthNumber
  • The findKthNumber function takes an integer n and an integer k as input and returns the kth lexicographically smallest number
  • The findKthNumber function uses a binary search approach to find the kth lexicographically smallest number
  • It first calculates the number of numbers less than or equal to n that can be formed by appending a digit from 1 to 9 to the current number
  • Then it recursively finds the kth lexicographically smallest number by finding the kth number that can be formed by appending a digit from 1 to 9 to the current number
  • The second findKthNumber function is used to calculate the number of numbers less than or equal to n that can be formed by appending a digit from 1 to 9 to the current number.

Solution Code:


class Solution {
public:
    int findKthNumber(int n, int k) {
        int result = 1;
        while (k > 1) {
            int count = findKthNumber(result, result + 1, n);
            if (count < k) {
                result++;
                k -= count;
            } else {
                result *= 10;
                k--;
            }
        }
        return result;
    }
    int findKthNumber(long p, long q, long n) {
        int result = 0;
        while (p <= n) {
            result += min(q, n + 1) - p;
            p *= 10;
            q *= 10;
        }
        return result;
    }
};

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

Find the Length of the Longest Common Prefix  (0) 2025.02.12
Extra Characters in a String  (0) 2025.02.12
Largest Number  (0) 2025.02.12
XOR Queries of a Subarray  (0) 2025.02.12
Count the Number of Consistent Strings  (0) 2025.02.12
블로그 이미지

짬뽕얼큰하게

,

Largest Number

알고리즘 2025. 2. 12. 08:57

Leetcode Problem:

Summary

  • Given a list of non-negative integers, arrange them to form the largest number and return it as a string.

Approach

  • The approach used is to first convert all the numbers into strings, then sort them in descending order based on a custom comparison function
  • The comparison function concatenates each pair of strings in both orders (ab and ba) and returns the one that results in the larger number
  • After sorting, the strings are concatenated in reverse order to form the largest possible number.

Complexity

  • O(n log n) due to the sorting operation, where n is the number of elements in the input list.

Explain

  • The solution code first converts all the numbers in the input list into strings
  • It then defines a custom comparison function `cmp` that takes two strings `a` and `b` as input
  • This function concatenates each pair of strings in both orders (ab and ba) and returns the one that results in the larger number
  • The `largestNumber` function then sorts the list of strings using this comparison function and concatenates them in reverse order to form the largest possible number
  • Finally, it checks if the resulting number starts with '0' and returns '0' if it does, to handle the case where all the numbers are zeros.

Solution Code:


class Solution {
public:
    static bool cmp(string a, string b){
        string aa = a + b;
        string bb = b + a;
        return aa < bb;
    }
    string largestNumber(vector& nums) {
        vector str_nums;
        for(int i = 0 ; i < nums.size(); i++){
            str_nums.push_back(to_string(nums[i]));
        }
        sort(str_nums.begin(), str_nums.end(), cmp);
        string ans = "";
        for(int i = str_nums.size() - 1; i >= 0 ; i--){
            ans += str_nums[i];
        }
        if (ans.find("0") == 0) return "0";
        return ans;
    }
};

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

Extra Characters in a String  (0) 2025.02.12
K-th Smallest in Lexicographical Order  (0) 2025.02.12
XOR Queries of a Subarray  (0) 2025.02.12
Count the Number of Consistent Strings  (0) 2025.02.12
Minimum Bit Flips to Convert Number  (0) 2025.02.12
블로그 이미지

짬뽕얼큰하게

,

Leetcode Problem:

Summary

  • Given an array of positive integers and queries where each query is a range, compute the XOR of elements in the range for each query.

Approach

  • The approach is to first compute the XOR of all elements in the array and then for each query, compute the XOR of the elements in the range by XORing the element at the end of the range with the XOR of the elements up to the second last element in the range.

Complexity

  • O(n + q) where n is the size of the array and q is the number of queries

Explain

  • The solution first computes the XOR of all elements in the array by iterating over the array and XORing each element with the previous one
  • Then for each query, it computes the XOR of the elements in the range by XORing the element at the end of the range with the XOR of the elements up to the second last element in the range
  • This is done by accessing the element at the end of the range and the element at the position before the end of the range, and XORing them
  • The result is then added to the answer vector.

Solution Code:


class Solution {
public:
    vector xorQueries(vector& arr, vector>& queries) {
        vector ans;
        for(int i = 1 ; i < arr.size(); i++){
            arr[i] = arr[i] ^ arr[i-1];
        }
        for(int i = 0 ; i < queries.size(); i++) {
            int a = queries[i][0];
            int b = queries[i][1];
            ans.push_back(arr[b] ^ (a-1 < 0 ? 0 : arr[a-1]));
        }
        return ans;
    }
};

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

K-th Smallest in Lexicographical Order  (0) 2025.02.12
Largest Number  (0) 2025.02.12
Count the Number of Consistent Strings  (0) 2025.02.12
Minimum Bit Flips to Convert Number  (0) 2025.02.12
Insert Greatest Common Divisors in Linked List  (0) 2025.02.12
블로그 이미지

짬뽕얼큰하게

,