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;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值