1. 程式人生 > >LeetCode Weekly Contest 112 (C++)

LeetCode Weekly Contest 112 (C++)

Welcome to the 112th LeetCode Weekly Contest

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, losing token[i] power, and gaining 1 point.
  • If we have at least 1 point, we may play the token face down, gaining token[i] power, and losing 1 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;
}