1. 这题出的真的乍一看到一点思路都没有.code
2. 参考别人的题解才看出端倪.blog
3. 首先看最大移动次数是多少.由于只要咱们将第一个数字stones[0]移动到stones[1]后,接下来就必定能够以间隔1按照剩下的缝隙填补,因此移动次数是stones[len-1]-stones[1]-len+2, 反过来从末尾往前看,移动次数是stones[len-2]-stones[0]-len+2, 所以最大移动次数是max(stones[len-1]-stones[1]-len+2, stones[len-2]-stones[0]-len+2).io
4. 最小移动次数.由于最终的结果是将数字放在连续的数轴上,相似于大小为stones.size()的窗口,所以用滑动窗口的思路.每一个窗口内的移动次数分别是stones.size()-(right-left+1).比较哪一个最小便可.class
5. 算最小次数时的一个特殊状况, 当相似[3,4,5,6,9]自己就连续时,最小次数是2, 3->8,9->7. 若是是[3,4,5,6,8]最小次数1,也不影响.甚至[3,4,5,6]自己就是连续,次数为0也不影响, 由于求的是最小次数.im
class Solution { public: vector<int> numMovesStonesII(vector<int>& stones) { sort(stones.begin(), stones.end()); int left=0, right=0; int len = stones.size(); vector<int> res(2); if(len<=2) return res; int minV = INT_MAX; while(right<stones.size()) { while(stones[right]-stones[left]+1>len) left++; if(right-left+1==len-1 && stones[right]-stones[left]+1==len-1) minV = min(minV, 2); else minV = min(minV, len-(right-left+1)); right++; } res[0] = minV; res[1] = max(stones[len-1]-stones[1]-len+2, stones[len-2]-stones[0]-len+2); return res; } };