LeetCode Weekly Contest 112 (C++)
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:
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;
}