leetcode problem solving thinking analysis 846 - 852 questions

  1. Yishoushunzi
    Alice has a hand given by an array of integers. Now she wants to rearrange the cards into groups so that each group is w in size and consists of W consecutive cards. If she can complete the grouping, it returns true; otherwise, it returns false.

Record whether each card has been used and find it in turn after sorting

class Solution {
public:
    bool isNStraightHand(vector<int>& hand, int groupSize) {
        int len = hand.size();
        // Two special cases
        if(len % groupSize != 0) return false; // Cannot divide by integer, return false directly
        if(groupSize == 1) return true; // groupSize of 1 directly returns true

        // sort
        sort(hand.begin(),hand.end());

        // Records whether array elements have been used
        vector<int> used(len,false);
        // i traverses the hand array for the first pointer 
        for(int i=0;i<len;i++){
            // Skip if element is already in use
            if(used[i]) continue;
            // The number of cards left is not enough to form a new W
            if(i>len-groupSize) return false;
            // Take use[i] as the first card in this hand and record that the card has been used
            int cur = hand[i];            
            used[i] = true;

            int tar = cur + 1; // tar is the next card to be found
            int end = cur + groupSize - 1;// end is the last card in this hand
            for(int j=i+1;j<len;j++){
                if(used[j]) continue; // Skip if used
                if(hand[j]>tar) return false;// Hand [J] > tar indicates that the required cards are missing
                else if(hand[j]==tar){
                    // hand[j]==tar indicates that the next required card has been found
                    used[j] = true;
 
                    if(hand[j]==end)break; // This card has been found. Jump out of the cycle and start looking for a new set of cards
                    // Not yet at end. Continue to find the next tar
                    else tar++;
                }
            }
        }
        return true;
    }
};

  1. Shortest path to all nodes
    There is an undirected connected graph composed of n nodes, and the nodes in the graph are numbered from 0 to n - 1. Give you an array graph to represent this graph. Where, graph[i] is a list consisting of all nodes directly connected to node I. Returns the length of the shortest path that can access all nodes. You can start and stop at any node, revisit the node multiple times, and reuse edges

Solution obtained by BFS + state compression

class Solution {
public:
    int shortestPathLength(vector<vector<int>>& graph) {
        int n = graph.size();

        // 1. Initialize the queue and tag array and store them in the starting point
        queue< tuple<int, int, int> > q; // The three attributes are IDX, mask and dist
        vector<vector<bool>> vis(n, vector<bool>(1 << n)); // Node number and current status
        for(int i = 0; i < n; i++) {
            q.push({i, 1 << i, 0}); // Store start point, start distance 0, mark
            vis[i][1 << i] = true;
        }

        // Start search
        while(!q.empty()) {
            auto [cur, mask, dist] = q.front(); // Pop up queue header element
            q.pop();

            // Find the answer and return the result
            if(mask == (1 << n) - 1) return dist;

            // extend
            for(int x : graph[cur]) {
                int nextmask = mask | (1 << x);
                if(!vis[x][nextmask]) {
                    q.push({x, nextmask, dist + 1});
                    vis[x][nextmask] = true;
                }
            }
        }
        return 0;
    }
};

  1. Letter shift
    There is a string S composed of lowercase letters and an integer array shifts. We call the next letter in the alphabet the shift of the original letter (because the alphabet is surrounded, 'Z' will become 'a'). For example, shift('a ') ='b', shift('t ') ='u', and shift('z ') ='a'. For each shift [i] = x, we will shift the first i+1 letter in S x times. Returns the final string after applying all these shifts to S.

Use of prefixes and

class Solution {
public:
    string shiftingLetters(string s, vector<int>& shifts) {
        vector<int>presum;
        long long sumall=shifts.back();
        presum.push_back(sumall);
        reverse(shifts.begin(),shifts.end());
        for(int i=1;i<shifts.size();i++){
            sumall%=26;
            sumall+=shifts[i];
            sumall%=26;
            presum.push_back(sumall);
        }
        reverse(presum.begin(),presum.end());
        //cout<<presum[2]<<endl;
        for(int i=0;i<s.size();i++){
            int inter=presum[i]%26;
            int index=s[i]-'a';
            s[i]=(inter+index)%26+'a';
        }
        return s;
    }
};
  1. Maximum distance to the nearest person
    Give you an array, seats represents a row of seats, where seats[i] = 1 means someone is sitting in seat I, and seats[i] = 0 means seat I is empty (subscript starts from 0). There is at least one empty seat and at least one person is already seated. Alex wants to sit in a seat that maximizes the distance between him and the person closest to him. Return to the maximum distance from him to the nearest person.

Double pointer sliding problem solving

class Solution {
public:
    int maxDistToClosest(vector<int>& seats) {
        int pre = -1;   //Previous seated position, initial value is - 1
        int maxdis = 0; //Maximum length between two seated positions
        int n = seats.size();
        for (int i = 0; i < n; i++) {
            if (seats[i] == 1) {    //Seated
                //First seat taken
                if (pre == -1) {
                    maxdis = i * 2;
                }
                else if (i - pre > 1) {
                    maxdis = max(maxdis, i - pre - 1);
                }
                pre = i;    //Update pre
            }
            
            //Non seated and last seat
            else if (i == n - 1) {
                maxdis = max(maxdis, 2 * (i - pre));
            }
        }
        return maxdis - maxdis / 2; //The maximum distance from the nearest person is maxdis - maxdis / 2
    }
};


  1. Rectangular area 2
    We give a (axis aligned) list of rectangles. For rectangle[i] = [x1, y1, x2, y2], where (x1, y1) is the coordinate of the lower left corner of rectangle I and (x2, y2) is the coordinate of the upper right corner of the rectangle. Find the total area covered by all rectangles in the plane. Since the answer may be too large, please return its modulus of 10 ^ 9 + 7.

Linear scan

class Solution 
{
private:
    const static int MOD = 1e9 + 7;
    const static int OPEN = 0;
    const static int CLOSE = 1;

    // Calculation width: in fact, it is just to continuously accumulate a larger difference of x
    int QueryWidth(multiset<pair<int,int>>& activate)
    {
        int res = 0;
        int maxX = -1;
        for (auto [x1, x2] : activate)
        {
            maxX = max(maxX, x1);
            // If x becomes larger, calculate the difference and accumulate a larger width
            res += max(0, x2 - maxX);
            // Constantly updated Max x
            maxX = max(maxX, x2);
        }
        return res;
    }

public:
    int rectangleArea(vector<vector<int>>& rectangles) 
    {
        vector<vector<int>> rec;
        for (auto v: rectangles)
        {
            rec.push_back({v[1], OPEN, v[0], v[2]});
            rec.push_back({v[3], CLOSE, v[0], v[2]});
        }
        // Sort scan from bottom to top
        sort(rec.begin(), rec.end());
        
        // Storage area and
        int res = 0;
        // Initialize the position of the first y
        int lastY = rec[0][0];
        // Abscissa of area to be calculated [x1,x2]
        // During the scanning process, each time OPEN is inserted, and CLOSE is deleted
        multiset<pair<int,int>> activate;

        for (const vector<int> r : rec)
        {
            int y = r[0];
            int state = r[1];
            int x1 = r[2];
            int x2 = r[3];

            // Cumulative area
            res = (res + (long long)QueryWidth(activate)*(y-lastY)) % MOD;
            // Update last y coordinate
            lastY = y;
            // For each OPEN, insert, and CLOSE, delete
            if (state == OPEN)
            {
                activate.insert({x1, x2});
            }
            else
            {
                activate.erase(activate.find(pair<int,int>{x1, x2}) );
            }
        }

        return res;
    }
};


  1. Noisy and rich
    In a group of N individuals (numbered 0, 1, 2,..., N-1), everyone has different amounts of money and different degrees of quietness. For convenience, we call the person numbered X "person x" for short. If we can be sure that person x is richer than person y, we will say richer[i] = [x, y]. Note that richer may only be a subset of valid observations. In addition, if the quiet degree of person x is q, we will say quiet[x] = q. Now, return to the answer answer, where answer[x] = y. the premise is that among all people who have no less than person x, person y is the quietest person (that is, the person with the smallest quiet value quiet[y]).

Sort according to the degree of money, and then compare it quietly to get the final solution.

class Solution {
public:
    vector<int> loudAndRich(vector<vector<int>>& richer, vector<int>& quiet) {
    	int n = quiet.size();
    	vector<vector<int>> g(n);//Digraph, the rich point to the poor
    	vector<int> indegree(n, 0);//Penetration
    	for(auto& r : richer)
    	{
    		g[r[0]].push_back(r[1]);
    		indegree[r[1]]++;
    	}
    	queue<int> q;//Point id
    	vector<int> ans(n, -1);
    	for(int i = 0; i< n; i++)
    		ans[i] = i;//The quietest thing is yourself
    	for(int i = 0; i < n; i++)
    	{
    		if(indegree[i] == 0)
    		{
    			q.push(i);
    			//The wealthiest person has an income of 0
    		}
    	}
    	while(!q.empty())
    	{
    		int id = q.front();//Person id
    		int q_val = quiet[ans[id]];
    		//So far, the quietest person is quiet
            q.pop();
    		for(auto nt : g[id])//People connected to him (poorer than him)
    		{
    			if(q_val < quiet[ans[nt]])
    			//The quieter person than nt is ans[nt], and its quietness value has no q_val small
    				ans[nt] = ans[id];
    			if(--indegree[nt] == 0)
    				q.push(nt);
    		}
    	}
    	return ans;
    }
};

  1. Peak index of mountain range array
    An array arr that meets the following properties is called a mountain array:
    arr.length >= 3
    There is i (0 < i < arr.length - 1) such that:
    arr[0] < arr[1] < ... arr[i-1] < arr[i]
    arr[i] > arr[i+1] > ... > arr[arr.length - 1]
    Give you the mountain array arr composed of integers, and return any subscript i satisfying arr [0] < arr [1] <... Arr [I - 1] < arr [i] > arr [i + 1] >... > arr [arr. Length - 1].

Binary search

class Solution {
public:
    int peakIndexInMountainArray(vector<int>& arr) 
    {
        int size = arr.size();
        int left = 0, right = size, mid = 0, ret = 0;

        while (left < right)
        {
            mid = (left + right) / 2;

            if (arr[mid] > arr[mid + 1])
            {
                if (arr[mid] > arr[mid - 1])
                {
                    ret = mid;
                    break;
                }

                right = mid;
                continue;
            }
            else
            {
                left = mid;
            }
        }

        return ret;
    }
};

Tags: Algorithm leetcode Interview

Posted on Sat, 20 Nov 2021 21:46:37 -0500 by memphis.rayy