- 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; } };

- 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; } };

- 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; } };

- 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 } };

- 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; } };

- 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; } };

- 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; } };