Daily question-1.2: daily question + 41 + 42

Posted by slshmily on Mon, 03 Jan 2022 08:24:27 +0100

Daily question-1.2: daily question + 41 + 42

1. Daily question 390: eliminate the game

subject

The list arr consists of all integers in the range [1, n] and is sorted strictly incrementally. Please apply the following algorithm to arr:
From left to right, delete the first number, and then delete every other number until you reach the end of the list.
Repeat the above steps, but this time from right to left. That is, delete the rightmost number, and then delete every other number.
Repeat these two steps from left to right and from right to left until there is only one number left.
Give you the integer n and return the last remaining number of arr.

Input: n = 9
Output: 6
Explanation:
arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
arr = [2, 4, 6, 8]
arr = [2, 6]
arr = 

Input: n = 1
Output: 1

1 <= n <= 10^9

thinking

Joseph problem. Joseph made it with dp.
First delete from left to right, then delete from right to left, and so on. It can be found that if the number before deletion is n, the number of deletions is int(n / 2).
We use f(n) to represent the last remaining number traversed by 1-n from left to right and then from right to left, and g(n) to represent the last remaining number traversed by 1-n from right to left and then from left to right.
The following rules can be found:

\[1. f(1)=1,g(1)=1\\ 2. f(n)=2∗g(n/2)\\ 3. f(n)+g(n)=n+1 \]

1 is the initial state.
2 assuming that the initial array is [1,2,3,4,5,6], the final remaining number is f(6). After the first round of traversal from left to right, the remaining number is [2,4,6], which is exactly 2 * [1,2,3], but at this time, we start to traverse from the right. The final remaining number is g(3). We can find that f(6)=2 * g(3). If the initial array length is odd, the result is the same.
3 assuming that f(n) finally leaves the k-th number from left to right, it can be found that the operations of g(n) and f(n) are symmetrical, and the rest is the k-th number from right to left. The sum of the two is n+1.
The formula derived from the final result is:

\[f(n)=2*(n/2+1-f(n/2)) \]

code

class Solution {
public:
int lastRemaining(int n) {
if(n == 1) return 1;
return 2 * (n / 2 + 1 - lastRemaining(n / 2));
}
};

2.41: combined sum

subject

Give you an unordered integer array nums. Please find the smallest positive integer that does not appear in it.
Please implement a solution with time complexity of O(n) and only use constant level additional space.

Input: nums = [1,2,0]
Output: 3

Input: nums = [3,4,-1,1]
Output: 2

Input: nums = [7,8,9,11,12]
Output: 1

1 <= nums.length <= 5 * 10^5
-2^31 <= nums[i] <= 2^31 - 1

thinking

Hash tables can achieve complexity o(n). But constant level space is required.
Using bucket sorting can satisfy the constant level space: 1 appears on nums, 2 on nums, N on nums[n-1], and other non positive numbers are ignored. For example, [3,4, - 1,1] will be sorted as [1, - 1,3,4]
Traverse the entire array before the operation, except int_ All numbers except min are subtracted by one to ensure that the subsequent numbers can meet nums[i] == i during swap.
Traverse nums, find the first number from 1 to n that should not be in the position, and return i + 1. If not, return n + 1. For example, the first num [i] in the sorted [1, - 1,3,4]= I is the number 1.

Complexity

The second layer of the while loop in the code will put a number in the correct position every time, so it can be executed at most N times, so the total time complexity is O(n).

code

class Solution {
public:
int firstMissingPositive(vector<int>& nums) {
int n = nums.size();
if(n == 0) return 1;
for(int i = 0; i < n; i++)
if(nums[i] != INT_MIN) nums[i] --;
for(int i = 0; i < n; i++){
while(nums[i] >= 0 && nums[i] < n && nums[i] != i && nums[i] != nums[nums[i]])
swap(nums[i], nums[nums[i]]);
}
for(int i = 0; i < n; i++)
if(nums[i] != i) return i + 1;
return n + 1;
}
};

3. 42: connected to rainwater

subject

Given n nonnegative integers to represent the height diagram of each column with width 1, calculate how much rain the columns arranged according to this can receive after rain.

Input: height = [0,1,0,2,1,0,1,3,2,1,2,1]
Output: 6
Explanation: the above is composed of an array [0,1,0,2,1,0,1,3,2,1,2,1] In this case, 6 units of rainwater can be connected (the blue part represents rainwater).

Input: height = [4,2,0,3,2,5]
Output: 9

n == height.length
1 <= n <= 2 * 10^4
0 <= height[i] <= 10^5

thinking

Monotonous stack practice.

code

class Solution {
public:
int trap(vector<int>& height) {
stack<int> sta;
int res = 0;
for(int i = 0; i < height.size(); i++){
int last = 0;
while(sta.size() && height[sta.top()] <= height[i]){
res += (height[sta.top()] - last) * (i - sta.top() - 1);
last = height[sta.top()];
sta.pop();
}
if(sta.size()) res += (height[i] - last) * (i - sta.top() - 1);
sta.push(i);
}

return res;
}
};```