链接:https://leetcode-cn.com/problems/moving-stones-until-consecutive-ii/
注意到这道题每次移动石子后,边界都会变窄,对于最大的移动次数,我们要使每次移动边界变窄的量最小。首次移动时,边界变窄的量是由
s
t
o
n
e
s
[
1
]
−
s
t
o
n
e
s
[
0
]
stones[1]-stones[0]
stones[1]−stones[0] 与
s
t
o
n
e
s
[
n
−
1
]
−
s
t
o
n
e
s
[
n
−
2
]
stones[n-1]-stones[n-2]
stones[n−1]−stones[n−2]决定的,我们取其中较小的一个,之后的每次移动我们都可以使边界变窄的量为1.
对于最小的移动次数,没有特别简便的计算法,可以使用滑动窗口,计算出将石子都移动到某个区间所需的移动次数。
C++代码:
class Solution {
public:
vector<int> numMovesStonesII(vector<int>& stones) {
sort(stones.begin(),stones.end());
int n = stones.size();
int Max = stones[n-1]-stones[0]+1-n - min(stones[1]-stones[0],stones[n-1]-stones[n-2])+1;
int i = 0;
int j = 0;
int Min = Max;
for(i = 0;i<n;i++)
{
while(j<n&&stones[j]-stones[i]+1<=n)
j++;
int cost = n-(j-i);
if(j-i==n-1&&stones[j-1]-stones[i]+1 == n-1)//此处j一定是大于等于1的
cost = 2;
Min = min(Min,cost);
}
return vector<int>{Min,Max};
}
};