# 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]) {
}
}
}
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;
}
};
```

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