初探双指针

双指针

双指针,顾名思义,是一种使用两个指针相互配合来求解问题的方法。

例1:排序数组中两个数组之和

    /**
     * 排序数组两数之和
     * 双指针
     *
     * @return
     */
    @Test
    public void test0331212() {
        int[] arr = new int[]{3, 2, 4};
        int target = 6;
        //要进行排序
        Arrays.sort(arr);
        int j = 0, k = arr.length - 1;

        //循环条件:两数之和不等于target
        while (arr[j] + arr[k] != target && k > j) {
            //移动指针
            if (arr[j] + arr[k] > target) {
                k--;
            } else {
                j++;
            }
        }
        System.out.println(Arrays.toString(new int[]{j, k}));
    }

例二:数组中和为零的三个数

    /**
     * 数组中和为0的三个数字
     */
    @Test
    public void test0331228() {
        List<List<Integer>> result = new LinkedList<>();
        int[] arr = new int[]{-1, 0, 1, 2, -1, -4};

        Arrays.sort(arr);
        int i = 0;
        while (i < arr.length - 2) {
            //在剩余的数组中查找两数之和为arr[i]的
            int j = i + 1, k = arr.length - 1;
            while (j < k) {
                if (arr[i] * (-1) == arr[j] + arr[k]) {
                    result.add(Arrays.asList(arr[i], arr[j], arr[k]));
                    int temp = arr[j];
                    //去重
                    while (temp == arr[j] && j < k) {
                        j++;
                    }
                } else if (arr[i] * (-1) > arr[j] + arr[k]) {
                    j++;
                } else {
                    k--;
                }
            }

            //这里也需要去重
            int temp = arr[i];
            while (i < arr.length && temp == arr[i]) {
                i++;
            }
        }

        System.out.println(result);
    }

例三:和大于等于k的最短子数组


    /**
     * 和大于或等于k的最短子数组
     */
    @Test
    public void test0331419() {
        int[] arr = new int[]{5, 1, 4, 3};
        int target = 7, min_length = Integer.MAX_VALUE, j = 0, k = 0, sum = 0;

        while (k < arr.length) {
            sum += arr[k];
            while (sum >= target && j <= k) {
                min_length = Math.min(min_length, k - j + 1);
                sum -= arr[j++];
            }
            k++;
        }
        min_length = min_length == Integer.MAX_VALUE ? 0 : min_length;
        System.out.println(min_length);
    }

例四:乘积小于k的连续子数组数

    /**
     * 乘积小于K的连续子数组的个数
     */
    @Test
    public void test0331431() {
        int[] arr = new int[]{10, 5, 2, 6};
        int target = 100, count = 0, j = 0, k = 0, product = 1;

        while (k < arr.length) {
            product *= arr[k];
            while (product >= target && j <= k) {
                product /= arr[j++];
            }
            count += j <= k ? k - j + 1 : 0;
            k++;
        }

        System.out.println(count);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值