Analysis of leetcode problem solving ideas 693 - 699 questions

Posted by a1amattyj on Fri, 28 Jan 2022 07:21:04 +0100

  1. Alternate bit binary number
    Given a positive integer, check whether its binary representation always alternates 0 and 1: in other words, the numbers of adjacent two digits in the binary representation will never be the same.

Get data by bit and XOR

class Solution {
public:
    bool hasAlternatingBits(int n) 
    {
        int a = n & 1;
        n = n >> 1;
        while (n)
        {
            int b = n & 1;
            n = n >> 1;
            if (b ^ a == 0)
            {
                return false;
            }
            a = b;
        }
        return true;
    }
};
  1. Maximum area of the island
    Given a non empty two-dimensional array grid containing some 0 and 1.
    An island is a combination of adjacent 1s (representing land). The "adjacent" here requires that two 1s must be adjacent horizontally or vertically. You can assume that all four edges of the grid are surrounded by 0 (representing water).
    Find the largest island area in the given two-dimensional array. (if there are no islands, the return area is 0.)

Traverse again, the searched value is 0, and those not searched continue to be detected

class Solution {
    int dfs(vector<vector<int>>& grid, int cur_i, int cur_j) {
        if (cur_i < 0 || cur_j < 0 || cur_i == grid.size() || cur_j == grid[0].size() || grid[cur_i][cur_j] != 1) {
            return 0;
        }
        grid[cur_i][cur_j] = 0;
        int di[4] = {0, 0, 1, -1};
        int dj[4] = {1, -1, 0, 0};
        int ans = 1;
        for (int index = 0; index != 4; ++index) {
            int next_i = cur_i + di[index], next_j = cur_j + dj[index];
            ans += dfs(grid, next_i, next_j);
        }
        return ans;
    }
public:
    int maxAreaOfIsland(vector<vector<int>>& grid) {
        int ans = 0;
        for (int i = 0; i != grid.size(); ++i) {
            for (int j = 0; j != grid[0].size(); ++j) {
                ans = max(ans, dfs(grid, i, j));
            }
        }
        return ans;
    }
};


  1. Count binary substring
    Given a string s, calculate the number of non empty (continuous) substrings with the same number of 0 and 1, and all 0 and 1 in these substrings are continuous. For repeated substrings, count the number of times they appear.

Traverse once, record the count of repeated substrings, and then calculate the minimum value with the number of repetitions last time, which is the number of repeated substrings, which can be accumulated.

class Solution {
public:
    int countBinarySubstrings(string s) 
    {
        int before = 0, cnt = 1, ret = 0, size = s.size();
        char c;

        if (size == 0) 
            return ret;

        c = s[0];
        for (int i = 1; i < size;)
        {
            while (i < size && c == s[i])
            {
                cnt++;
                i++;
            }
            ret += min(cnt, before);
            before = cnt;
            cnt = 0;
            c = s[i];
        }

        return ret;
    }
};
  1. Degree of array
    Given a non empty integer array nums containing only non negative numbers, the definition of the degree of the array refers to the maximum frequency of any element in the array.
    Your task is to find the shortest continuous sub array with the same size as num in num and return its length.

The use of hash table, in which an array with a length of 3 is used to identify the number of occurrences, the position of the first occurrence of the number in the original array and the position of the last occurrence of the number in the original array

class Solution {
public:
    int findShortestSubArray(vector<int>& nums) 
    {
        unordered_map<int, int[3]> mp;
        int n = nums.size();
        for (int i = 0; i < n; i++) 
        {
            if (mp.count(nums[i])) 
            {
                mp[nums[i]][0]++;
                mp[nums[i]][2] = i;
            } 
            else 
            {
                mp[nums[i]][0] = 1;
                mp[nums[i]][1] = i;
                mp[nums[i]][2] = i;                                
            }
        }
        int maxNum = 0, minLen = 0;
        for (auto& [_, vec] : mp) 
        {
            if (maxNum < vec[0]) 
            {
                maxNum = vec[0];
                minLen = vec[2] - vec[1] + 1;
            } 
            else if (maxNum == vec[0]) 
            {
                if (minLen > vec[2] - vec[1] + 1) 
                {
                    minLen = vec[2] - vec[1] + 1;
                }
            }
        }
        return minLen;
    }
};


  1. Divided into k equal subsets
    Given an integer array nums and a positive integer k, find out whether it is possible to divide the array into k non empty subsets, the sum of which is equal.

Backtracking pruning or hashing can be used

class Solution {
public:
    bool canPartitionKSubsets(vector<int>& nums, int k) {
        sort(nums.rbegin(), nums.rend());
        int sum = accumulate(nums.begin(), nums.end(), 0);
        if (sum % k != 0) return false;
        int avg = sum / k;

        vector<int> vi(nums.size(), 0);
        return dfs(nums, vi, avg, 0, k);
    }

    bool dfs(vector<int>& nums, vector<int>& vi, int target, int sum, int k) {
        if (k == 0) return true;

        int firstIdx = -1;
        for (int i = 0; i < nums.size(); i++) {
            if (vi[i] == 1) continue;
            firstIdx = (firstIdx == -1) ? i : firstIdx;
            if (sum == 0 && i != firstIdx) return false;

            int temp = sum + nums[i];
            if (temp > target) continue;

            int nextK = (temp == target) ? k - 1 : k;
            int nextSum = (temp == target) ? 0 : temp;

            vi[i] = 1;
            if (dfs(nums, vi, target, nextSum, nextK)) return true;
            vi[i] = 0;
        }
        return false;
    }
};


class Solution {
public:
    bool canPartitionKSubsets(vector<int>& nums, int k) 
    {
        int maxNum = 0, cnt = 0, goal = 0, dif = 0, left = 0;
        bool bFind = false;
        unordered_map<int, stack<int>> m_map;

        for (int i = 0; i < nums.size(); i++)
        {
            cnt += nums[i];
            maxNum = max(maxNum, nums[i]);
            m_map[nums[i]].push(i);
        }

        if (cnt % k) return false;

        goal = cnt / k;
        if (maxNum > goal) return false;

        cnt = 0;
        left = goal;
        for (int i = 0; i < nums.size(); ++i)
        {
            if (nums[i] == - 1) continue;

            dif = left - nums[i];

            if (dif == 0)
            {
                cnt++;
                left = goal;
                nums[i] = -1;
                continue;
            }   

            auto tempStack = m_map[dif];
            if (tempStack.size() > 0)
            {
                bFind = false;
                while (tempStack.size() > 0)
                {
                    int index = tempStack.top();
                    if (nums[index] == -1)
                    {
                        tempStack.pop();
                        continue;
                    }
                    else
                    {
                        cnt++;
                        left = goal;
                        nums[index] = -1;
                        tempStack.pop();
                        bFind = true;                       
                        break;
                    }
                }
            }

            if (!bFind)
            {
                goal -= nums[i];
            }
        }

        if (cnt == k) 
            return true;
        else
            return false;
    }
};
  1. Falling box
    Returns a list of stack heights ans. Each stacking height ans[i] represents the highest stacking height of all stable blocks after the falling of blocks represented by positions[0], positions[1],..., positions[i].

Segment tree solution

class Solution {
public:
    int a[10005], mark[10005];

    void build(int p, int l, int r) {
        if (l == r) {
            a[p] = 0;
            mark[p] = 0;
            return;
        }
        int mid = l + (r - l) / 2;
        build(p << 1, l, mid);
        build(p << 1 | 1, mid + 1, r);
        a[p] = max(a[p << 1], a[p << 1 | 1]);
    }

    void push_down(int p) {
        mark[p << 1] = max(mark[p], mark[p << 1]);
        mark[p << 1 | 1] = max(mark[p], mark[p << 1 | 1]);
        a[p << 1] = max(a[p << 1], mark[p << 1]);
        a[p << 1 | 1] = max(a[p << 1 | 1], mark[p << 1 | 1]);
        mark[p] = 0;
    }

    int query(int p, int l, int r, int ql, int qr) {
        if (qr < l || ql > r) return 0;
        else if (ql <= l && qr >= r) return a[p];
        else {
            if (mark[p]) {
                push_down(p);
            }
            int mid = l + (r - l) / 2;
            if (qr <= mid) return query(p << 1, l, mid, ql, qr);
            else if (ql > mid) return query(p << 1 | 1, mid + 1, r, ql, qr);
            else return max(query(p << 1, l, mid, ql, qr),query(p << 1 | 1, mid + 1, r, ql, qr));
        }
    }

    void update(int p, int l, int r, int ul, int ur, int val) {
        if (ur < l || ul > r) return;
        else if (ul <= l && ur >= r) {
            a[p] = max(a[p], val);
            mark[p] = max(mark[p], val);
        } else {
            if (mark[p]) push_down(p);
            int mid = l + (r - l) / 2;
            update(p << 1, l, mid, ul, ur, val);
            update(p << 1 | 1, mid + 1, r, ul, ur, val);
            a[p] = max(a[p << 1], a[p << 1 | 1]);
        }
    }


    vector<int> fallingSquares(vector<vector<int>>& positions) {
        vector<int> arr;
        for (auto &p : positions) {
            arr.push_back(p[0]);
            arr.push_back(p[0] + p[1] - 1);
        }
        sort(arr.begin(), arr.end());
        arr.erase(unique(arr.begin(), arr.end()), arr.end());
        int n = arr.size();
        unordered_map<int, int> mp;
        for (int i = 0; i < n; ++i) mp[arr[i]] = i;
        build(1, 0, n - 1);
        vector<int> ans;
        int maxh = 0;
        for (auto &p : positions) {
            int ql = mp[p[0]], qr = mp[p[0] + p[1] - 1];
            int h = query(1, 0, n - 1, ql, qr);
            maxh = max(maxh, h + p[1]);
            ans.push_back(maxh);
            update(1, 0, n - 1, ql, qr, h + p[1]);
        }
        return ans;
    }
};

Topics: Algorithm data structure Interview string Dynamic Programming