了解最小掉期的特定解决方案,以分组所有1&#2nd;问题

发布于 2025-02-06 17:34:59 字数 2274 浏览 2 评论 0原文

我正在查看leetcode问题 2134。将所有1分组在一起的最小互换ii

a 交换被定义为在数组中取两个不同的位置并交换了它们中的值。

a 圆形阵列定义为一个阵列,我们认为 first 元素和 last 元素为 相邻。

给定二进制循环 array nums,返回将所有1的最小交换数在的任何位置

一起

我正在尝试研究其他人如何提出自己的解决方案。我遇到了这个特定的逻辑:

class Solution {
    public int minSwaps(int[] nums) {
        // number of ones    
        int cntones=Arrays.stream(nums).sum();
        // worst case answer
        int rslt=nums.length;
        // position lft and figure better value for min/rslt
        int holes = 0;
        for(int i=0;i<cntones;i++) {
            if(nums[i]==0)
                holes++;
        }
        // better value for rslt from lft to rgt
        // up to index of cntones.
        rslt = Math.min(rslt, holes);
        
        // they have a test case with one element 
        // and that trips up if you dont do modulo
        int rgt=cntones % nums.length;
        for(int lft=0;lft<nums.length;lft++) {
            rslt=Math.min(rslt,holes);
            if(nums[lft]!=nums[rgt]) 
                if(nums[rgt]==1)
                    holes--;
                else 
                    holes++;
            rgt=(rgt+1)%nums.length;
        }
        return rslt;
    }
}
  1. 为什么最坏的情况是输入数组的长度? 我在想等一下,最坏的情况不是[0,1,0,1,0,1 ...],其中0和1交替?你能给我一个例子吗?

  2. 我想#hores在某些情况下可能是一个可能的解决方案,从窗口的固定长度(总1)数计数,但由于我不了解最坏的情况,所以rslt <rslt << /code>来自问题1,下面的线路也使我陷入困境。

      //从LFT到RGT的RSLT的更好价值
    //到Cntones的索引。
    RSLT = Math.min(RSLT,孔);
     
  3. 关于下面的modulo,我不认为cntones可以大于nums.length,而这会一直导致0?我正在考虑使用一个元素的情况,您必须检查一个元素是0还是1。

      //他们有一个带有一个元素的测试用例 
    //如果您不做模仿,那就去了
    int rgt = cntones%nums.length; 
     
  4. 由于#1〜#3,循环的最后一个对我没有意义...

I am looking at the LeetCode problem 2134. Minimum Swaps to Group All 1's Together II:

A swap is defined as taking two distinct positions in an array and swapping the values in them.

A circular array is defined as an array where we consider the first element and the last element to be adjacent.

Given a binary circular array nums, return the minimum number of swaps required to group all 1's present in the array together at any location.

I am trying to study how other people came up with solutions of their own. I came across this particular one, but I don't understand the logic:

class Solution {
    public int minSwaps(int[] nums) {
        // number of ones    
        int cntones=Arrays.stream(nums).sum();
        // worst case answer
        int rslt=nums.length;
        // position lft and figure better value for min/rslt
        int holes = 0;
        for(int i=0;i<cntones;i++) {
            if(nums[i]==0)
                holes++;
        }
        // better value for rslt from lft to rgt
        // up to index of cntones.
        rslt = Math.min(rslt, holes);
        
        // they have a test case with one element 
        // and that trips up if you dont do modulo
        int rgt=cntones % nums.length;
        for(int lft=0;lft<nums.length;lft++) {
            rslt=Math.min(rslt,holes);
            if(nums[lft]!=nums[rgt]) 
                if(nums[rgt]==1)
                    holes--;
                else 
                    holes++;
            rgt=(rgt+1)%nums.length;
        }
        return rslt;
    }
}
  1. Why is the worst case, the length of the input array?
    I'm thinking wait, wouldn't the worst case be something like [0,1,0,1,0,1...] where 0's and 1's are alternating? Can you give me an example?

  2. I suppose #of holes can potentially be a possible solution in some cases, from counting 0's in a fixed length (the number of total 1's) of a window but because I do not understand the worst case, rslt from question #1, below line stumps me as well.

    // better value for rslt from lft to rgt
    // up to index of cntones.
    rslt = Math.min(rslt, holes);
    
  3. About the modulo below, I don't think cntones can ever be bigger than nums.length, in turn which will result in 0 all the time? I'm thinking for the case with one element, you'd have to check whether that one element is 0 or 1. How does below line cover that edge case?

    // they have a test case with one element 
    // and that trips up if you dont do modulo
    int rgt=cntones % nums.length; 
    
  4. Due to #1~#3 the last for loop makes no sense to me...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

我偏爱纯白色 2025-02-13 17:34:59

为什么最坏的情况是输入数组的长度?

首先要说的是,互换只有在以1的价格交换0时才有用。其次,第二次交换相同的数字是没有意义的,因为这种双重交换可以通过单个交换来实现。因此,我们可以说,掉期数量的上限是0位数或1位数的数量(最少)。实际上,这是一个高估,因为至少一个1位应该能够保持不动。但是,让我们暂时忽略这一点。为了达到最坏的情况,应该有多达1个数字,因此我们的长度的一半与最坏的情况一样。当然,通过初始化的价值大于(如长度),我们不会受到伤害。

交替数字的示例将通过保持一半的1位数不动,并在它们之间的孔中移动其余的1位数来解决。因此,这意味着我们有许多互换等于数组长度的四分之一。

下面的线路也使我陷入困境。

  rslt = Math.min(RSLT,孔);
 

正如您所说,有一个窗口在圆形阵列上移动,这代表了最终的最终情况,所有一位数都应结束。因此,它设定了目标。显然,该窗口内的一位数字无需交换。该窗口内的每个0位数都必须用当前在该窗口外面的1位数交换。这样做将达到目标,因此到达该特定目标窗口的掉期数量等于该窗口内部的孔数(0位数)。

由于每个可能的窗口都进行了练习,因此我们有兴趣找到窗口的最佳位置,即孔数(交换)被最小化的孔数(交换)。这就是这条代码行动。 RSLT是“到目前为止”的最小值,holes是我们对当前窗口的新价值。如果较少,则应将rslt更新到它。这就是在此声明中发生的事情。

关于下面的modulo,我不认为cntones可以大于nums.length,而这会一直导致0?我正在考虑使用一个元素的情况,您必须检查一个元素是0还是1。

  int rgt = cntones%nums.length; 
 

该Modulo仅适用于cntones等于 nums.length。您是对的,它永远不会超过。但是,可能相等的情况(当输入只有1位数时)。并且由于rgt将用作索引,因此它应该不是等于nums.length,因为这是该插槽大批。

由于#1〜#3,循环的最后一个对我没有意义...

从上面的细节中应该可以清楚地清楚。该循环一次每次移动窗口,并保持变量holes逐步更新。当然,我们可以决定计算每个窗口中从头开始的孔数,但这将浪费时间。当我们从一个窗口到另一个窗口时,我们只在左侧丢失一个数字,并在右侧获得一位,因此我们可以使用该信息更新hores,并知道该信息中有多少个孔当前窗口 - 从lft开始并运行(圆形)到rgt的窗口。如果我们在左侧丢失的数字与右边获得的数字相同,那么我们显然没有更改孔的数量。在它们不同的地方,我们要么与上一个窗口相比,要么赢或失去一个洞。

Why is the worst case, the length of the input array?

First note that a swap is only useful when it swaps a 0 with 1. Secondly, it makes no sense to swap the same digit a second time, as the result of such double swap could have been achieved with a single swap. So we can say that an upper limit for the number of swaps is the number of 0-digits or number of 1-digits (which ever is the least). In fact, this is an overestimation, because at least one 1-digit should be able to stay unmoved. But let's ignore that for now. To reach that worst case, there should be as many 1 as 0 digits, so then we have half of the length as worst case. Of course, by initialising with a value that is greater than that (like the length) we do no harm.

The example of alternating digits would be resolved by keeping half of those 1-digits unmoved, and moving the remaining 1-digits in the holes between them. So that means we have a number of swaps that is equal to about one fourth of the length of the array.

below line stumps me as well.

rslt = Math.min(rslt, holes);

As you said, there is a window moving over the circular array, which represents the final situation where all 1-digits should end up. So it sets the target to work towards. Obviously, the 1-digits that are already within that window don't need to be swapped. Each 0-digit inside that window has to be swapped with a 1-digit that is currently outside that window. Doing that will reach the target, and so the number of swaps for reaching that particular target window is equal to the number of holes (0-digits) inside that window.

As that exercise is done for each possible window, we are interested to find the best position of the window, i.e. the one where the number of holes (swaps) is minimised. That is what this line of code is doing. rslt is the minimum "so far" and holes is the fresh value we have for the current window. If that is less, then rslt should be updated to it. That's what happens in this statement.

About the modulo below, I don't think cntones can ever be bigger than nums.length, in turn which will result in 0 all the time? I'm thinking for the case with one element, you'd have to check whether that one element is 0 or 1. How does below line cover that edge case?

int rgt=cntones % nums.length; 

That modulo only serves for the case that cntones is equal to nums.length. You are right that it will never exceed it. But the case where it is equal is possible (when the input only has 1-digits). And as rgt is going to be used as an index, it should not be equal to nums.length as that is an undefined slot in the array.

Due to #1~#3 the last for loop makes no sense to me...

It should be clear from the above details. That loop moves the window with one step at a time, and keeps the variable holes updated incrementally. Of course, we could have decided to count the number of holes from scratch in each window, but that would be a waste of time. As we go from one window to the next, we only lose one digit on the left and gain one on the right, so we can just update holes with that information and know how many holes there are in the current window -- the one that starts at lft and runs (circular) to rgt. In case the digit that we lose at the left is the same as the one we gain at the right, we obviously didn't change the number of holes. Where they are different, we either win or lose one hole in comparison with the previous window.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文