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 = [6] 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 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:
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[0], 2 on nums[1], 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; } };```