双指针

作者: Wilbur_ | 来源:发表于2021-09-13 09:39 被阅读0次

    LC605 这道题是分类讨论,果然还是用到了离散数学里面的思想,你要覆盖所有情况, 我当时自己想就没有想全面,这实际上就是自己思维的漏洞,平时生活中这种事情也应该想到,就是考虑全面。比如昨天开车就没有考虑堵车的情况

    思维不够缜密,但可以通过这种练习来不断提高。

    说回这道题,这道题一共有3种情况,第一种是有一个1为边界的时候,比如左边全是0或者右边都是0,这时候总共能放入的1 有k/2下取整这么多。(这个k是当前线段的长度)当然这个k/2是找规律找出来的。

    第二种情况就是在两个1之间,这时候代码里其实不需要特判,因为你遇到1直接跳过就可以了,然后用双指针(就是第二个指针代表遇到的第二个1) 来求这段区间的长度。这时候不用特判就可直接求里面能放多少个1,因为天然符合两个1之间(双指针的做用) 而这里面能放 (k-1)/2 下取整这么多个数(也是通过找规律来得到这个公式)。

    我原本以为第三种情况就是右边界的情况,但实际上这种情况在代码里可以直接用没有1(整个数组没有1) 来覆盖掉

    第三种情况就是没有1

    也就是说如果j(第二个指针) == arr.length 的时候, 那么右边就没有1, 这时候无论是整个数组没有1,还是左边有个1,这段区间的长度里面能够放的1**都为 (k+1)/2 下取整

    代码太强了,我看了好几遍才发现这两个if判断直接能够排除第三种(没有1),因为双指针是直接贪心地走右边,那么如果第二个指针能够到最后一位,那直接让k++就可以了(前面判断过i是否为0) 如果i不是0,那么k就不用+1,而他原本就是直接求出k-1的长度(k本身是真正的长度,但他直接把k存成了k-1,这样之后就不用考虑第二种情况了(两个1之间)。
    代码

    class Solution {
        public boolean canPlaceFlowers(int[] flowerbed, int n) {
            if (n == 0) return true;
            boolean leftBound = true, inBetween = false;
            int count = 0, m = flowerbed.length;
            for (int i = 0; i < m; i++) {
                if (flowerbed[i] == 1) continue;
                int j = i;
                while (j < m && flowerbed[j] == 0) {
                    j++;
                }
                int k = j - i - 1; // 直接存k-1,这样不用再算(k-1)之后 再(k-1)/2下取整了
                if (i == 0) k++; //特判左边界,如果为0,那就是第一种情况,这时候能够放下的1就是k/2个了,所以k++;
                if (j == flowerbed.length) k++; // 如果第二个指针是最后一位了,那么无论之前是啥情况,我们都要k+1,(如果左指针是0,那么我们之前if已经判断过了,如果不是0,我们也要k++,因为第一种情况,也就是只有一个1的边界的时候,我们能够放k/2个1
                count += k / 2;
                i = j;
            }
            return count >= n;
        }
    }
    

    相关文章

      网友评论

          本文标题:双指针

          本文链接:https://www.haomeiwen.com/subject/pmjzwltx.html