力扣:两数之和,内外都用双指针,四分大法

    public int[] twoSum(int[] nums, int target) {
        int[] result = {0, 1};
        if (nums.length <= 2) {
            return result;
        }

        for (int i = 0, j = nums.length - 1; i < j; i++, j--) {
            if (nums[i] + nums[j] == target) {
                // Lucky
                result[0] = i;
                result[1] = j;
                return result;
            }

            // should be in [i+1, j-1], find them with double pointers.
            int x = target - nums[i];
            int y = target - nums[j];
            for (int k = i + 1, m = j - 1; k <= m; k++, m--) {
                result[0] = i;
                if (nums[k] == x) {
                    result[1] = k;
                    return result;
                } else if (nums[m] == x) {
                    result[1] = m;
                    return result;
                }

                result[1] = j;
                if (nums[k] == y) {
                    result[0] = k;
                    return result;
                } else if (nums[m] == y) {
                    result[0] = m;
                    return result;
                }
            }
        }

        return result;
    }

利用双指针从两头往中间遍历,不仅在主loop中使用,对内层loop也同样采用双指针的方式。因此,在找到满足要求的数之前,双指针会不断地向中间移动,缩小查找的范围。这使得算法的时间复杂度更低,可以达到 O(n/2logn)。

具体实现中,可以先将数组排序,然后使用双指针从两个方向开始遍历。如果左右指针之和等于 target,则直接返回;否则,内部使用双指针从低到高遍历区间 [i+1, j-1],查找满足要求的数。

需要注意的是,当主loop的双指针之和恰好是target时,可以直接返回结果,避免进行不必要的操作。同时,当主loop的左右指针之和已经大于 target 时,可以减少内部loop的次数,提高查找效率。

总的来说,该算法利用双指针从两头往中间遍历,缩小了查找的范围,从而提高了查找效率,时间复杂度为 O(n/2logn),是相对比较优秀的算法实现。

你可能感兴趣的:(算法,数据结构,c++)