zoukankan      html  css  js  c++  java
  • 1040. Moving Stones Until Consecutive II

    问题:

    给定一个数组stones代表每一块石头的位置,

    每次可对两边界的两块石头调整位置,只能向非边界的位置移动。

    求解,要最终使得所有的石头连续摆放(即他们的位置连续),最多和最少分别需要移动多少次?

    Example 1:
    Input: [7,4,9]
    Output: [1,2]
    Explanation: 
    We can move 4 -> 8 for one move to finish the game.
    Or, we can move 9 -> 5, 4 -> 6 for two moves to finish the game.
    
    Example 2:
    Input: [6,5,4,3,10]
    Output: [2,3]
    We can move 3 -> 8 then 10 -> 7 to finish the game.
    Or, we can move 3 -> 7, 4 -> 8, 5 -> 9 to finish the game.
    Notice we cannot move 10 -> 2 to finish the game, because that would be an illegal move.
    
    Example 3:
    Input: [100,101,104,102,103]
    Output: [0,0]
     
    
    Note:
    3 <= stones.length <= 10^4
    1 <= stones[i] <= 10^9
    stones[i] have distinct values.
    

      

    解法:

    sliding windows

    这里的windows则是我们想要的最终连续石头的位置。那么windows.size=A(stones).size

    分类解决:

    ■1. 最多移动的次数:(most case)

    分别从左右两边考虑,

    leftmost:尽量让所有的石头都能成为左边界(如下图)

    分两步:

    step1:把A[0]放到A[1]的下一个空位。(尽量想让A[0]靠近左边,但是有且只能往非边界的位置放的话,只能是最近的A[1]的下一个空位)

    step2:由于A[0]已经开始对A[1]下一个空位开始填充,那么,从A[1]开始,左边界逐次递增++1,一直到最后一位A[n-1]向前推windows.size-1个(window的开头元素)

    上述两步合起来

    step1:1 步

    step2:A[n-1]-(n-1) - A[1] 步 (左窗口-A[1])

    则有:

        leftmost=A[n-1]-(n-1) - A[1] + 1;

    rightmost同理可得:

    step1:1 步

    step2:A[n-2] - (A[0]+n-1) 步 (A[n-2]-右窗口)

        rightmost=A[n-2] - (A[0]+n-1) + 1;

    然后取左右两种可能的最大值。

        most=max(leftmost, rightmost);

    ■2. 最少移动的次数:

    又分两种情况:

    一般case:(如下图黄框)

        只需要尽量将窗口外的石头,移入窗口空位即可,这样最小移动次数,即是:窗口内空位的个数(==窗口外石头的个数)

    角落case:

        空位在左右边界的情况,由于不能直接用窗口外的石头填充空位,则需要至少移动 2 步。(如下图绿框)

    我们要求最少移动的次数的话,则是求上述两种case中移动最少的情况,

    一般case:则需要找到窗口内空位个数最少的情况

    角落case:=定值 2

    因此我们滑动窗口,窗口size确定,控制右窗口 j 从A[0]开始,往最后的A[n-1]滑动,

    (用窗口size确定左窗口 i )

    在这期间遍历所有的窗口可能,找到移动次数最少的可能。

    参考代码:

     1 class Solution {
     2 public:
     3     vector<int> numMovesStonesII(vector<int>& stones) {
     4         sort(stones.begin(), stones.end());
     5         int n=stones.size();
     6         int most=0, least=INT_MAX;
     7         //most:
     8         int leftmost=stones[n-1]-(n-1) - stones[1] + 1;
     9         int rightmost=stones[n-2] - (stones[0]+n-1) + 1;
    10         most=max(leftmost, rightmost);
    11         
    12         //least: find sliding windows[i~j]: which has the least space.
    13         int i=0;
    14         for(int j=0; j<n; j++){
    15             while(stones[j]-stones[i]>=n) i++;
    16             //find A[i]~A[j] -> [windows.size==n]
    17             if(j-(i-1)==(n-1) && stones[j]-stones[i]==(n-1)-1){
    18                 //corner case: [1,2,3,4]...10:
    19                 //i=0,j=3 A[i]=1, A[j]=4
    20                 //size(i~j)=n-1, A[i]..A[j]->连续: A[j]-A[i]=size(i~j)-1=(n-1)-1
    21                 least=min(least, 2);
    22             }else{
    23                 //normal case: sum of spaces
    24                 //window:A[i]~A[j]
    25                 //totle size=n, sum of spaces=totle size-cout(A[i]..A[j])
    26                 //=n-(j-(i-1))
    27                 least=min(least, n-(j-(i-1)));
    28             }
    29         }
    30         return {least, most};
    31     }
    32 };
  • 相关阅读:
    WLC-Download 3-party CA to WLC
    WLC-生成CSR操作
    MSE-初始化MSE
    Nexus-产品认识
    Nexus-配置VDC
    Nexus-VDC(Virtual Device Context)
    Nexus-FEX基础配置
    Nexus-配置vPC 实验三
    Nexus-配置vPC 实验二
    Nexus-配置vPC 实验一
  • 原文地址:https://www.cnblogs.com/habibah-chang/p/13044739.html
Copyright © 2011-2022 走看看