koenjazh-CNfresde
짬뽕얼큰하게의 맨땅에 헤딩 :: '릿코드' 태그의 글 목록 (26 Page)

Leetcode Problem:

Summary

  • Given two strings source and target, and two character arrays original and changed, find the minimum cost to convert source to target using any number of operations.

Approach

  • Dynamic programming is used to find the minimum cost
  • The cost of changing each character in source to the corresponding character in target is calculated and stored in a 2D array minCost
  • Then, the minimum cost of changing each character in source to any character in target is calculated using the Floyd-Warshall algorithm
  • Finally, the minimum cost to convert source to target is calculated by summing up the minimum cost of changing each character in source to the corresponding character in target.

Complexity

  • O(n^3), where n is the length of the strings source and target.

Explain

  • The solution first initializes a 2D array minCost with all elements set to 1234567890
  • Then, it calculates the minimum cost of changing each character in source to the corresponding character in target and stores it in minCost
  • After that, it uses the Floyd-Warshall algorithm to calculate the minimum cost of changing each character in source to any character in target
  • Finally, it calculates the minimum cost to convert source to target by summing up the minimum cost of changing each character in source to the corresponding character in target.

Solution Code:


class Solution {
public:
    long long minCost[26][26];
    long long minimumCost(string source, string target, vector& original, vector& changed, vector& cost) {
        for(int i = 0; i < 26; i++){
            for(int j = 0 ; j < 26; j++){
                minCost[i][j] = 1234567890;
            }
        }

        for(int i = 0 ; i < original.size(); i++){
            int a = original[i] -'a';
            int b = changed[i] - 'a';
            if (minCost[a][b] > cost[i]){
                minCost[a][b] = cost[i];
            }
        }

        for(int k = 0 ; k < 26; k++){
            for(int i = 0 ; i < 26; i++){
                if (k == i) continue;
                for(int j = 0 ; j < 26; j++){
                    if(k == j || i == j) continue;
                    if (minCost[i][j] <= minCost[i][k] + minCost[k][j]){
                        continue;
                    }
                    minCost[i][j] = minCost[i][k] + minCost[k][j];
                }
            }
        }
        long long ans = 0;
        for(int i = 0 ; i < source.size(); i++){
            int a = source[i] - 'a';
            int b = target[i] - 'a';
            if (a == b) continue;
            if(minCost[a][b] == 1234567890) return -1;
            ans += minCost[a][b];
        }
        return ans;
    }
};

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

Count Number of Teams  (0) 2025.02.04
Second Minimum Time to Reach Destination  (0) 2025.02.04
Find the City With the Smallest Number of Neighbors at a Threshold Distance  (0) 2025.02.04
Sort an Array  (0) 2025.02.04
Sort the Jumbled Numbers  (0) 2025.02.04
블로그 이미지

짬뽕얼큰하게

,

Leetcode Problem:

Summary

  • Find the city with the smallest number of cities that are reachable through some path and whose distance is at most distanceThreshold.

Approach

  • The solution uses Floyd-Warshall algorithm to find the shortest path between all pairs of cities, then iterates through each city to count the number of cities that are reachable within the distanceThreshold
  • The city with the smallest count that has the greatest number is returned.

Complexity

  • O(n^3)

Explain

  • The solution first initializes a 2D array dis to store the shortest distance between each pair of cities
  • It then iterates through each edge in the edges array and updates the dis array
  • After that, it uses Floyd-Warshall algorithm to find the shortest path between all pairs of cities
  • Finally, it iterates through each city and counts the number of cities that are reachable within the distanceThreshold
  • The city with the smallest count that has the greatest number is returned.

Solution Code:


class Solution {
public:
        int findTheCity(int n, vector>& edges, int distanceThreshold) {
        vector> dis(n, vector(n, 10001));
        int res = 0, smallest = n;
        for (auto& e : edges)
            dis[e[0]][e[1]] = dis[e[1]][e[0]] = e[2];
        for (int i = 0; i < n; ++i)
            dis[i][i] = 0;
        for (int k = 0; k < n; ++k)
            for (int i = 0; i < n; ++i)
                for (int j = 0; j < n; ++j)
                    dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
        for (int i = 0; i < n; i++) {
            int count = 0;
            for (int j = 0; j < n; ++j)
                if (dis[i][j] <= distanceThreshold)
                    ++count;
            if (count <= smallest) {
                res = i;
                smallest = count;
            }
        }
        return res;
    }
};

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

Second Minimum Time to Reach Destination  (0) 2025.02.04
Minimum Cost to Convert String I  (0) 2025.02.04
Sort an Array  (0) 2025.02.04
Sort the Jumbled Numbers  (0) 2025.02.04
Longest Strictly Increasing or Strictly Decreasing Subarray  (0) 2025.02.03
블로그 이미지

짬뽕얼큰하게

,

Sort an Array

알고리즘 2025. 2. 4. 08:39

Leetcode Problem:

Summary

  • Sort an array of integers in ascending order without using built-in O(nlog(n)) time complexity and smallest space complexity possible.

Approach

  • The approach used is a modified merge sort algorithm
  • The array is divided into two halves until each subarray contains only one element, and then the subarrays are merged back together in sorted order.

Complexity

  • O(nlog(n))

Explain

  • The solution code uses a modified merge sort algorithm to sort the array
  • The merge function takes three parameters: the left index, the right index, and the current index
  • It compares the elements at the left and right indices and swaps them if necessary
  • The merge_sort function recursively divides the array into two halves until each subarray contains only one element, and then it merges the subarrays back together in sorted order
  • The time complexity of the solution is O(nlog(n)) because the merge sort algorithm has a time complexity of O(nlog(n)) and the space complexity is O(n) because the temporary array has a size of n.

Solution Code:


class Solution {
public:
    void merge(vector& nums, int l , int mid, int r){
        int i = l;
        int j = mid + 1;
        int cur = i;
        int tmp[50001];
        while(i <= mid && j <= r){
            if (nums[i] <= nums[j]){
                tmp[cur++] = nums[i++];
            } else {
                tmp[cur++] = nums[j++];
            }
        }
        while(i <= mid){
            tmp[cur++] = nums[i++];
        }
        for(i = l; i < cur; i++){
            nums[i] = tmp[i];
        }
    }
    void merge_sort(vector& nums, int l, int r){
        if (l >= r) return;
        int mid = (l + r) / 2;
        merge_sort(nums, l, mid);
        merge_sort(nums, mid+1, r);
        merge(nums, l, mid, r);
    }
    vector sortArray(vector& nums) {
        merge_sort(nums, 0, nums.size() - 1);
        return nums;
    }
};
블로그 이미지

짬뽕얼큰하게

,

Leetcode Problem:

Summary

  • The problem requires sorting an array of integers based on their mapped values in a shuffled decimal system.

Approach

  • The solution uses a modified merge sort algorithm to sort the array
  • It first creates a temporary array to store the sorted elements, and then merges the sorted subarrays into the original array.

Complexity

  • O(n log n)

Explain

  • The solution defines a helper function `getNum` to calculate the mapped value of a given integer
  • It then uses a modified merge sort algorithm to sort the array
  • The `merge` function is used to merge two sorted subarrays into one, and the `merge_sort` function recursively divides the array into smaller subarrays and sorts them
  • The sorted subarrays are then merged back into the original array using the `merge` function.

Solution Code:


class Solution {
public:
    int tmp[30001];
    int getNum(vector& mapping, int a){
        int pow = 1;
        int res = 0;
        if (a == 0) return mapping[a];
        while(a){
            res += (mapping[a%10])*pow;
            pow *= 10;
            a /= 10;
        }
        return res;
    }
    void merge(vector& mapping, vector& nums, int l, int mid, int r ){
        int i = l;
        int j = mid + 1;
        int cur = i;
        while(i <= mid && j <= r){
            if(getNum(mapping, nums[i]) <= getNum(mapping, nums[j])){
                tmp[cur++] = nums[i++];
            } else {
                tmp[cur++] = nums[j++];
            }
        }
        while(i <= mid){
            tmp[cur++] = nums[i++];    
        }
        for(i = l ; i < cur; i++){
            nums[i] = tmp[i];
        }
    }
    void merge_sort(vector& mapping, vector& nums, int l, int r ){
        if (l >= r) return;
        int mid = (l + r) / 2;
        merge_sort(mapping, nums, l, mid);
        merge_sort(mapping, nums, mid+1, r);
        merge(mapping, nums, l, mid, r);
    }
    vector sortJumbled(vector& mapping, vector& nums) {
        merge_sort(mapping, nums, 0, nums.size() - 1);
        return nums;
    }
};
블로그 이미지

짬뽕얼큰하게

,

Leetcode Problem:

Summary

  • Find the length of the longest strictly increasing or decreasing subarray in a given array of integers.

Approach

  • The solution uses a dynamic programming approach
  • It maintains two variables, inc and dec, to track the length of the longest increasing and decreasing subarrays ending at the current position
  • The maximum length between these two subarrays is updated at each step.

Complexity

  • O(n), where n is the length of the input array
  • This is because the solution iterates through the array once.

Explain

  • The solution starts by initializing three variables: inc, dec, and ans
  • inc and dec are used to track the length of the longest increasing and decreasing subarrays ending at the current position, respectively
  • ans is used to store the maximum length of these subarrays
  • The solution then iterates through the array, updating inc and dec based on whether the current element is greater than or less than the previous element
  • If the current element is equal to the previous element, inc and dec are reset to 1
  • At each step, the solution updates ans to be the maximum of its current value and the maximum of inc and dec
  • Finally, the solution returns ans, which represents the length of the longest strictly increasing or decreasing subarray in the input array.

Solution Code:


class Solution {
public:
    int longestMonotonicSubarray(vector& nums) {
        int inc = 1;
        int dec = 1;
        int ans = 1;
        for(int i = 1 ; i < nums.size(); i++){
            if (nums[i-1] < nums[i]){
                inc++;
                dec = 1;
            }else if (nums[i-1] > nums[i]){
                inc = 1;
                dec++;
            } else{
                dec = 1;
                inc = 1;
            }
            
            ans = max(ans, max(inc, dec));
        }
        return ans;
    }
};

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

Sort an Array  (0) 2025.02.04
Sort the Jumbled Numbers  (0) 2025.02.04
Sort Array by Increasing Frequency  (0) 2025.02.03
Sort the People  (0) 2025.02.03
Build a Matrix With Conditions  (0) 2025.02.03
블로그 이미지

짬뽕얼큰하게

,

Leetcode Problem:

Summary

  • Given an array of integers, sort the array in increasing order based on the frequency of the values
  • If multiple values have the same frequency, sort them in decreasing order.

Approach

  • The solution uses a frequency count array to store the frequency of each value, then sorts the array using a modified merge sort algorithm
  • The modified merge sort algorithm uses a temporary array to store the merged elements and then copies them back to the original array.

Complexity

  • O(n log n)

Explain

  • The solution first creates a frequency count array `cnt` to store the frequency of each value
  • Then it calls the `merge_sort` function to sort the array
  • The `merge_sort` function recursively divides the array into two halves and sorts them separately
  • Then it merges the two sorted halves using the `merge` function
  • The `merge` function compares the frequencies of the values and sorts them in increasing order
  • If multiple values have the same frequency, it sorts them in decreasing order
  • Finally, the solution returns the sorted array.

Solution Code:


class Solution {
    int cnt[300] = {0};
    int tmp[100];
    void merge(vector& nums, int l, int mid, int r){
        int i = l;
        int j = mid + 1;
        int cur = i;
        while( i <= mid && j <= r){
            if (cnt[nums[i] + 100] < cnt[nums[j] + 100]){
                tmp[cur++] = nums[i++];
            } 
            else if(cnt[nums[i] + 100] == cnt[nums[j] + 100] && nums[i] > nums[j]){
                tmp[cur++] = nums[i++];
            }
            else{
                tmp[cur++] = nums[j++];
            }
        }
        while(i <= mid){
            tmp[cur++] = nums[i++];
        }
        for(i = l; i < cur; i++){
            nums[i] = tmp[i];
        }
    }
    void merge_sort(vector &nums, int l, int r){
        if (l >= r) return;
        int mid = (l + r) / 2;
        merge_sort(nums, l, mid);
        merge_sort(nums, mid+1, r);
        merge(nums, l, mid, r);
    }    
public:
    vector frequencySort(vector& nums) {
        for(int i = 0 ; i < nums.size(); i++){
            cnt[nums[i] + 100]++;
        }
        merge_sort(nums, 0, nums.size() -1);
        return nums;
    }
};

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

Sort the Jumbled Numbers  (0) 2025.02.04
Longest Strictly Increasing or Strictly Decreasing Subarray  (0) 2025.02.03
Sort the People  (0) 2025.02.03
Build a Matrix With Conditions  (0) 2025.02.03
Number of Good Leaf Nodes Pairs  (0) 2025.02.03
블로그 이미지

짬뽕얼큰하게

,

Sort the People

알고리즘 2025. 2. 3. 07:43

Leetcode Problem:

Summary

  • Given an array of names and heights, sort the names in descending order by height.

Approach

  • Merge Sort algorithm is used to sort the heights array first, then use the sorted heights array to sort the names array.

Complexity

  • O(n log n)

Explain

  • The merge_sort function is a recursive function that divides the array into two halves until each subarray has one element
  • The merge function then merges the subarrays back together in sorted order
  • After sorting the heights array, the names array is sorted based on the heights array
  • The names array is then returned in a vector of strings.

Solution Code:


class Solution {
public:
    vector h;
    int tmp[1001];
    void merge(int* arr, int l, int mid, int r){
        int i = l;
        int j = mid + 1;
        int cur = l;
        while(i <= mid && j <= r){
            int num1 = arr[i];
            int num2 = arr[j];
            if(h[num1] >= h[num2]){
                tmp[cur++] = arr[i++];
            }else{
                tmp[cur++] = arr[j++];
            }
        }
        while(i <= mid){
            tmp[cur++] = arr[i++];
        }
        for(i = l; i < cur; i++){
            arr[i] = tmp[i];
        }
    }
    void merge_sort(int* arr, int l, int r){
        if (l >= r) return;
        int mid = (l + r) / 2;
        merge_sort(arr, l, mid);
        merge_sort(arr, mid+1, r);
        merge(arr, l, mid, r);
    }

    vector sortPeople(vector& names, vector& heights) {
        h = heights;
        int* arr = new int[heights.size()];
        for(int i = 0 ; i < heights.size(); i++){
            arr[i] = i;
        }
        merge_sort(arr, 0, heights.size()-1);
        vector ans;
        for(int i = 0 ; i < heights.size(); i++){
            int n = arr[i];
            ans.push_back(names[n]);
        }
        return ans;
    }
};
블로그 이미지

짬뽕얼큰하게

,

Leetcode Problem:

Summary

  • Given a 2D array of row conditions and column conditions, build a k x k matrix that contains each number from 1 to k exactly once and satisfies the conditions.

Approach

  • The solution uses a depth-first search (DFS) approach to find a Hamiltonian path in the graph
  • It first constructs two graphs, one for row conditions and one for column conditions
  • Then, it checks if there is a cycle in either graph using DFS
  • If there is a cycle, it returns an empty matrix
  • Otherwise, it uses another DFS to find a Hamiltonian path in the graph and constructs the matrix based on the path.

Complexity

  • O(k * m * n * k) where m and n are the number of row conditions and column conditions respectively

Explain

  • The solution starts by constructing two graphs, one for row conditions and one for column conditions
  • It then checks if there is a cycle in either graph using DFS
  • If there is a cycle, it returns an empty matrix
  • Otherwise, it uses another DFS to find a Hamiltonian path in the graph and constructs the matrix based on the path
  • The Hamiltonian path is used to ensure that each number from 1 to k is used exactly once in the matrix and that the row and column conditions are satisfied.

Solution Code:


class Solution {
public:
    bool traversalCycle(int cur, vector> graph, int color[]){
        color[cur] = 1;
        for(int i = 0 ; i < graph[cur].size(); i++){
            int next = graph[cur][i];
            if (color[next] == 0 && traversalCycle(next, graph, color)){
                return true;
            } else if (color[next] == 1){
                return true;
            }
        }
        color[cur] = 2;
        return false;
    }
    bool findCycle(int k, vector> &graph){
        int *color = new int[k];
        for(int i = 0 ; i < k; i++){
            color[i] = 0;
        }
        for(int i = 0 ; i < k ;i++){
            if (color[i] != 0) continue;
            if (traversalCycle(i, graph, color)){
                return true;
            }
        }
        return false;
    }

    void traversalAnswer(int cur, vector> &graph, vector &ans, bool visited[]){
        if(visited[cur]) return;
        visited[cur] = true;
        for(int i = 0 ; i < graph[cur].size(); i++){
            int next = graph[cur][i];
            traversalAnswer(next, graph, ans, visited);
        }
        ans.push_back(cur);
    }
    void getAnswer(int k, vector> &graph, vector &ans){
        bool *visited = new bool[k];
        for(int i = 0 ; i < k; i++){
            visited[i] = false;
        }
        for(int i = 0; i < k; i++){
            if (visited[i]) continue;
            traversalAnswer(i, graph, ans, visited);
        }
        reverse(ans.begin(), ans.end());
    }

    vector> buildMatrix(int k, vector>& rowConditions, vector>& colConditions) {
        vector> graph1(k);
        vector> graph2(k);
        for(int i = 0 ; i < rowConditions.size(); i++){
            int a = rowConditions[i][0];
            int b = rowConditions[i][1];
            graph1[a - 1].push_back(b - 1);
        }
        for(int i = 0 ; i < colConditions.size(); i++){
            int a = colConditions[i][0];
            int b = colConditions[i][1];
            graph2[a - 1].push_back(b - 1);
        }
        if (findCycle(k, graph1) || findCycle(k, graph2)){
            return {};
        }

        vector ans1, ans2;
        getAnswer(k, graph1, ans1);
        getAnswer(k ,graph2, ans2);

        vector> ans;
        map m;
        for(int i = 0 ; i < k; i++){
            m[ans2[i]] = i;
            ans.push_back(vector());
            for(int j = 0 ; j < k; j++){
                ans[i].push_back(0);
            }
        }
        for(int i = 0 ; i < k; i++){
            ans[i][m[ans1[i]]] = ans1[i] + 1;
        }
        return ans;
    }
};

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

Sort Array by Increasing Frequency  (0) 2025.02.03
Sort the People  (0) 2025.02.03
Number of Good Leaf Nodes Pairs  (0) 2025.02.03
Delete Nodes And Return Forest  (0) 2025.02.03
Step-By-Step Directions From a Binary Tree Node to Another  (0) 2025.02.03
블로그 이미지

짬뽕얼큰하게

,

Leetcode Problem:

Summary

  • The problem is to find the number of good leaf node pairs in a binary tree where a pair of two different leaf nodes is said to be good if the length of the shortest path between them is less than or equal to a given distance.

Approach

  • The approach used is to perform a depth-first traversal of the binary tree and store the distances of the leaf nodes in a vector
  • Then, for each pair of leaf nodes, check if the distance between them is less than or equal to the given distance
  • If it is, increment the count of good pairs.

Complexity

  • O(n log n) due to the sorting of the vector of leaf node distances, where n is the number of nodes in the tree.

Explain

  • The solution code defines a class Solution with a method countPairs that takes the root of a binary tree and an integer distance as input
  • It initializes a variable dist to store the distance and a variable ans to store the count of good pairs
  • The method traversal is a helper function that performs a depth-first traversal of the binary tree and stores the distances of the leaf nodes in a vector
  • The method countPairs calls the traversal method and initializes the variable dist
  • It then calls the traversal method and checks for each pair of leaf nodes if the distance between them is less than or equal to the given distance
  • If it is, it increments the count of good pairs
  • Finally, it returns the count of good pairs.

Solution Code:


/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    int dist;
    int ans = 0;
    vector traversal(TreeNode* node){
        if (node->left == nullptr && node->right == nullptr) return {1};
        vector v;
        if (node->left){
            v = traversal(node->left);
        }
        if (node->right){
            vector tmp = traversal(node->right);
            for(int i = 0 ; i < tmp.size(); i++){
                for(int j = 0 ; j < v.size(); j++){
                    if (v[j] + tmp[i] <= dist){
                        ans++;
                    }
                }
            }
            v.insert(v.end(), tmp.begin(), tmp.end());
            
        }
        for(int i = 0 ; i < v.size(); i++){
            v[i] += 1;
        }
        return v;
    }
    int countPairs(TreeNode* root, int distance) {
        dist = distance;
        traversal(root);
        return ans;
    }
};

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

Sort the People  (0) 2025.02.03
Build a Matrix With Conditions  (0) 2025.02.03
Delete Nodes And Return Forest  (0) 2025.02.03
Step-By-Step Directions From a Binary Tree Node to Another  (0) 2025.02.03
Create Binary Tree From Descriptions  (0) 2025.02.03
블로그 이미지

짬뽕얼큰하게

,

Leetcode Problem:

Summary

  • Given a binary tree and a list of values to delete, return the roots of the trees in the remaining forest.

Approach

  • We use a depth-first search approach to traverse the binary tree
  • We first create a vector to store the roots of the trees in the remaining forest
  • Then, we iterate over the list of values to delete and for each value, we traverse the binary tree to find and delete the nodes with the given value
  • After deleting the nodes, we check if the node has children
  • If it does, we add the children to the vector of roots
  • Finally, we return the vector of roots.

Complexity

  • O(n * m) where n is the number of nodes in the binary tree and m is the number of values to delete.

Explain

  • The solution code defines a class Solution with a method delNodes that takes the root of a binary tree and a vector of values to delete as input
  • It uses a helper function traversal to delete the nodes with the given values
  • The traversal function checks if the current node has the given value and if so, it deletes the node and its children
  • If the node does not have the given value, it recursively calls itself on the left and right children of the node
  • After deleting the nodes, it checks if the node has children and if so, it adds the children to the vector of roots
  • The method returns the vector of roots.

Solution Code:


/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    bool traversal(TreeNode* ptr, vector &ans, int target){
        if(ptr == nullptr) return false;
        if(ptr->val ==  target){
            for(int i = 0 ; i < ans.size(); i++){
                if (ans[i] == nullptr) continue;
                if (ans[i]->val == target){
                    ans[i] = nullptr;
                    break;
                }
            }
            if (ptr->left){
                ans.push_back(ptr->left);
            }
            if (ptr->right){
                ans.push_back(ptr->right);
            }
            return true;
        }

        if (traversal(ptr->left, ans, target)){
            ptr->left = nullptr;
        }
        if (traversal(ptr->right, ans, target)){
            ptr->right = nullptr;
        }
        return false;
    }
    vector delNodes(TreeNode* root, vector& to_delete) {
        vector ans = {root};
        for(int i = 0 ; i < to_delete.size(); i++){
            for(int j = 0 ; j < ans.size(); j++){
                traversal(ans[j], ans, to_delete[i]);
            }
        }
        vector ans2;
        for(int i = 0 ; i < ans.size(); i++){
            if (ans[i] == nullptr) continue;
            ans2.push_back(ans[i]);
        }
        return ans2;
    }
};
블로그 이미지

짬뽕얼큰하게

,