Minimum Increment to Make Array Unique
Given an array of integers A, a move consists of choosing any
A[i]
, and incrementing it by1
.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
andpopped
with distinct values, returntrue
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:
0 <= pushed.length == popped.length <= 1000
0 <= pushed[i], popped[i] < 1000
pushed
is a permutation ofpopped
.pushed
andpopped
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 <= stones.length <= 1000
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 of0
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.
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:
tokens.length <= 1000
0 <= tokens[i] < 10000
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;
}
}