[LeetCode ] Weekly Contest 112

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/GYH0730/article/details/84561927

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.

Example 1:

Input: [1,2,2]
Output: 1
Explanation:  After 1 move, the array could be [1, 2, 3].

Example 2:

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.

题意:给出一个数组,一个move操作可以使数组中的任意一个数加1,问最少多少次操作可以使这个数组中每个元素都不一样。

思路:先对数组排序,再开一个标记数组,从头开始遍历,如果这个元素没有被标记过,就标记,用pre记录一下最新被标记的变量;如果这个元素已经被标记过了,就把这个元素改为pre+1,再标记,记录答案。

C代码:

int cmp(const void * a,const void * b)
{
    return *(int *)a - *(int *)b;
}
int minIncrementForUnique(int* A, int ASize) {
    if(ASize == 0) return 0;
    int vis[400005],i;
    memset(vis,0,sizeof(vis));
    qsort(A,ASize,sizeof(int),cmp);
    int res = 0,pre;
    for(i = 0; i < ASize; i++) {
        if(!vis[A[i]]) {
            vis[A[i]] = 1;
            pre = A[i];
        }
        else {
            pre++;
            vis[pre] = 1;
            res += pre - A[i];
        }
    }
    return res;
}

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.

Example 1:

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

Example 2:

Input: pushed = [1,2,3,4,5], popped = [4,3,5,1,2]
Output: false
Explanation: 1 cannot be popped before 2.

Note:

  1. 0 <= pushed.length == popped.length <= 1000
  2. 0 <= pushed[i], popped[i] < 1000
  3. pushed is a permutation of popped.
  4. pushed and popped have distinct values.

题意:给出入栈和出栈的顺序,判断是否合法。

思路:建立一个栈,遍历出栈数组,如果该出栈元素在栈头,那就直接出栈就行了;如果不在栈头,就遍历入栈数组,把该元素之前的所有元素都入栈。

C++代码:

#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
    bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
        if(pushed.size() == 0) return true;
        stack<int> s;
        int flag = 0;
        int j = 0;
        for(int i = 0; i < popped.size(); i++) {
            if(!s.empty() && s.top() == popped[i]) {
                s.pop();
                continue;
            }
            else {
                int f = 0;
                for(; j < pushed.size(); j++) {
                    if(pushed[j] == popped[i]) {
                        f = 1;
                        j++;
                        break;
                    }
                    s.push(pushed[j]);
                }
                if(f) continue;
            }
            flag = 1;
            break;
        }
        return !flag;
    }
};

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?

Example 1:

Input: stones = [[0,0],[0,1],[1,0],[1,2],[2,1],[2,2]]
Output: 5

Example 2:

Input: stones = [[0,0],[0,2],[1,1],[2,0],[2,2]]
Output: 3

Example 3:

Input: stones = [[0,0]]
Output: 0

Note:

  1. 1 <= stones.length <= 1000
  2. 0 <= stones[i][j] < 10000

题意:给出平面上的坐标点,每个坐标点上都有一个石子,每次move可以去掉同行或同列的一个石子。问最多能进行多少次move?

思路:每一个连通块内都可以进行num-1次move,num为连通块内石子的个数,用并查集找一下连通块以及每个连通块的石子数目就行了。

Java代码:

public class Solution {
	int[] pre = new int[1005];
	int[] sum = new int[1005];
	public int find(int x) {
		if(x == pre[x]) return x;
		return pre[x] = find(pre[x]);
	}
	public int removeStones(int[][] stones) {
		int fx,fy,res;
		for(int i = 0; i < stones.length; i++) {
			pre[i] = i;
			sum[i] = 1;
		}
		for(int i = 0; i < stones.length; i++) {
			for(int j = 0; j < stones.length; j++) {
				if(i == j) continue;
				if(stones[i][0] == stones[j][0] ||
					stones[i][1] == stones[j][1]) {
					fx = find(i);
					fy = find(j);
					if(fx != fy) {
						pre[fy] = fx;
						sum[fx] += sum[fy];
					}
				}
			}
		}
		res = 0;
		for(int i = 0; i < stones.length; i++) {
			if(pre[i] == i) {
				res += sum[i] - 1;
			}
		}
		return res;
    }
}

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 1point.

Return the largest number of points we can have after playing any number of tokens.

Example 1:

Input: tokens = [100], P = 50
Output: 0

Example 2:

Input: tokens = [100,200], P = 150
Output: 1

Example 3:

Input: tokens = [100,200,300,400], P = 200
Output: 2

Note:

  1. tokens.length <= 1000
  2. 0 <= tokens[i] < 10000
  3. 0 <= P < 10000

题意:n个tokens,开始有P能量,0分,每一个token都只能用1次,如果此时能量大于等于tokens所需要的能量,那么能量减掉t这个token需要的能量,分数加1;如果分数大于0,可以分数减掉1,能量加上tokens的能量。输出能获得的最大能量。

思路:贪心,对tokens排序,维护两个指针,用能量小的来涨分数,用分来买能量大的,记录最优解。

Java代码:

public class Solution {
	public int bagOfTokensScore(int[] tokens, int P) {
        Arrays.sort(tokens);
        int res,i,j,points;
        res = points = i = 0;
        j = tokens.length - 1;
        while(i <= j) {
        	if(P >= tokens[i]) {
        		P -= tokens[i];
        		points++;
        		res = Math.max(res, points);
        		i++;
        	}
        	else if(points != 0) {
        		points--;
        		P += tokens[j];
        		j--;
        	}
        	else break;
        }
        return res;
    }
}

猜你喜欢

转载自blog.csdn.net/GYH0730/article/details/84561927
今日推荐