Welcome to the 112th LeetCode Weekly Contest
- 945. Minimum Increment to Make Array Unique - Medium
- 946. Validate Stack Sequences - Medium
- 947. Most Stones Removed with Same Row or Column - Medium
- 948. Bag of Tokens - Medium
945. Minimum Increment to Make Array Unique
Given an array of integers A, a move consists of choosing any A[i]
, and incrementing it by 1
.
Return the least number of moves to make every value in A
unique.
Input: [1, 2, 2] Output: 1
Explanation: After 1 move, the array could be [1, 2, 3].
Input: [3, 2, 1, 2, 1, 7] Output: 6
Explanation: After 6 moves, the array could be [3, 4, 1, 2, 5, 7]. It can be shown with 5 or less moves that it is impossible for the array to have all unique values.
解:
这题就是排序,然后后边的数如果比前边的小,要变成前边的数+1,就行了,计算出为了达到这种效果,加了多少1就行。
int minIncrementForUnique(vector<int>& A) {
sort(A.begin(), A.end());
int steps = 0;
for(int i = 1; i < A.size(); i++)
if(A[i] <= A[i - 1])
{
steps += A[i - 1] - A[i] + 1;
A[i] = A[i - 1] + 1;
}
return steps;
}
946. Validate Stack Sequences
Given two sequences pushed
and popped
with distinct values, return true
if and only if this could have been the result of a sequence of push and pop operations on an initially empty stack.
Input: pushed = [1,2,3,4,5], popped = [4,5,3,2,1] Output: true
Explanation: We might do the following sequence:
push(1), push(2), push(3), push(4), pop() -> 4, push(5), pop() -> 5, pop() -> 3, pop() -> 2, pop() -> 1
Input: pushed = [1,2,3,4,5], popped = [4,3,5,1,2] Output: false
Explanation: 1 cannot be popped before 2.
解:
这道题就是模拟一下stack的运作,先放进去的不可能先拿出来,后放的一定是先出来。按照给出的popped顺序进行弹出,如果能够按照给的顺序全部弹出,那就是对的,否则就是错的。每次压入一个数后就判断是不是要按照题目要求弹出,是的话依次弹出,不是的话,就继续压入。(其实可以加速的,比如按序弹出时候,top和popped对应位置不一样,那肯定是错的)。
bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
stack<int> st;
int i = 0;
for(auto p : pushed)
{
st.push(p);
while(!st.empty() && st.top() == popped[i])
{
++i;
st.pop();
}
}
return i == popped.size();
}
947. Most Stones Removed with Same Row or Column
On a 2D plane, we place stones at some integer coordinate points. Each coordinate point may have at most one stone.
Now, a move consists of removing a stone that shares a column or row with another stone on the grid.
What is the largest possible number of moves we can make?
Input: stones = [ [0, 0], [0, 1], [1, 0], [1, 2], [2, 1], [2, 2] ] Output: 5
Input: stones = [ [0, 0], [0, 2], [1, 1], [2, 0], [2, 2] ] Output: 3
Input: stones = [ [0, 0] ] Output: 0
解:
这次的 contest 只有这道题没有思路,看了解答使用的是并查集(Union Find Set)的思想,并没有看懂= =看懂了再修改这篇博客吧、
948. Bag of Tokens
You have an initial power P
, an initial score of 0
points, and a bag of tokens.
Each token can be used at most once, has a value token[i]
, and has potentially two ways to use it.
- If we have at least
token[i]
power, we may play the token face up, losingtoken[i]
power, and gaining1
point. - If we have at least
1
point, we may play the token face down, gainingtoken[i]
power, and losing1
point.
Return the largest number of points we can have after playing any number of tokens.
Input: tokens = [ 100 ], P = 50 Output: 0
Input: tokens = [ 100, 200 ], P = 150 Output: 1
Input: tokens = [ 100, 200, 300, 400 ], P = 200 Output: 2
解:
就是说,手上有一个初始power,和一袋子没有顺序的tokens,一个tokens可以用一次,也可以选择不用。使用方式有两种,一种是消耗手里的 power,使用 value 小于手里 power 的 token,获得一个 point,或者是用一个 point(初始为0)来获取一个token 的 value,使他成为手中的 power。
思路就是先排序,每次用手里的 power 换尽可能多的 token 得到 points,然后用一个 points 来获取 value 最大的 token 的能量,再利用一些 trick 加速整个过程。
int bagOfTokensScore(vector<int>& tokens, int power)
{
sort(tokens.begin(), tokens.end());
int points = 0, l = 0, r = tokens.size() - 1, maxp = -1; // left, right
if (accumulate(tokens.begin(), tokens.end(), 0) <= power) // 可以直接全换成points
return tokens.size();
while (l < r)
{
if (tokens[l] >= power) break; // 没得token可换了
while (tokens[l] <= power)
{
// 用power换尽可能多的token(所以从小的开始换)
power -= tokens[l];
++l;
++points;
}
if (r - l <= 1) break; // r和l相邻的话, 之后就是points减1再加1,不可能影响结果
--points;
power += tokens[r--]; // 用一个point换没用过的token中最大的
}
return points;
}