返回

巧解难题!通过 LeetCode 167 理解两数之和 II

见解分享

深入剖析 LeetCode 167:两数之和 II 算法难题

探索算法的奥秘

在浩瀚的编程领域,算法难题犹如暗夜中的繁星,它们闪烁着智慧的光芒,吸引着求知者不断探索。LeetCode 167 两数之和 II 便是一颗璀璨的明星,考验着我们的问题解决能力和算法思维。

题目概述

给定一个下标从 1 开始的整数数组 numbers ,该数组已按非递减顺序排列,请你从数组中找出满足相加之和等于目标数 target 的两个数。 找到满足条件的两数后,返回它们的下标 ij,其中 1 <= i < j <= numbers.length

解法一:双指针法

双指针法 是一种高效的算法策略,它利用两个指针遍历数组,从不同方向逼近目标值。对于 LeetCode 167,我们使用两个指针分别指向数组开头和结尾,然后逐步向中间收缩。

算法步骤:

  1. 初始化两个指针,left 指向数组开头(index 为 1),right 指向数组结尾(index 为 numbers.length)。
  2. 计算当前指针指向元素之和 sum
  3. 如果 sum 等于 target,则找到了满足条件的两数,返回下标 ij
  4. 如果 sum 小于 target,则 left 右移一步,指向下一个元素。
  5. 如果 sum 大于 target,则 right 左移一步,指向上一个元素。
  6. 重复步骤 2-5,直到找到满足条件的两数或遍历完整个数组。

代码示例:

import java.util.Arrays;

class Solution {
    public int[] twoSum1(int[] numbers, int target) {
        int left = 1, right = numbers.length;
        while (left < right) {
            int sum = numbers[left] + numbers[right];
            if (sum == target) {
                return new int[] { left, right };
            } else if (sum < target) {
                left++;
            } else {
                right--;
            }
        }
        return new int[] { -1, -1 };
    }
}

解法二:二分查找法

二分查找法 是一种在排序数组中快速查找元素的算法。对于 LeetCode 167,我们可以将双指针法中的一个指针替换为二分查找,以提高效率。

算法步骤:

  1. 初始化指针 left 指向数组开头(index 为 1)。
  2. 使用二分查找在数组中查找 target - numbers[left]
  3. 如果找到了 target - numbers[left],则找到了满足条件的两数,返回下标 left 和二分查找找到的 index。
  4. 如果没有找到 target - numbers[left],则 left 右移一步,指向下一个元素。
  5. 重复步骤 2-4,直到找到满足条件的两数或遍历完整个数组。

代码示例:

import java.util.Arrays;

class Solution {
    public int[] twoSum2(int[] numbers, int target) {
        int left = 1;
        while (left < numbers.length) {
            int complement = target - numbers[left];
            int index = Arrays.binarySearch(numbers, left + 1, numbers.length, complement);
            if (index >= 0) {
                return new int[] { left, index + 1 };
            }
            left++;
        }
        return new int[] { -1, -1 };
    }
}

性能分析

双指针法和二分查找法都是时间复杂度为 O(n) 的高效算法。然而,在某些情况下,二分查找法的性能优势会更加明显。这是因为二分查找法可以在对数时间内找到目标元素,而双指针法需要遍历整个数组。

总结

LeetCode 167 两数之和 II 是一道经典的算法难题,它考验着我们的问题解决能力和算法思维。通过本文对双指针法和二分查找法的深入剖析,相信你已经掌握了这道题目的精髓。在未来的编程之旅中,希望这些算法技巧能够助你一臂之力,轻松破解算法难题。

常见问题解答

1. 双指针法和二分查找法哪个更好?

在时间复杂度上,双指针法和二分查找法都是 O(n)。然而,在某些情况下,二分查找法的性能优势会更加明显,特别是在数组长度较大时。

2. 如何选择使用哪个算法?

如果数组已排序,则二分查找法通常是更好的选择。如果数组未排序,则双指针法是唯一可行的选择。

3. 这两种算法是否可以在其他问题中使用?

双指针法和二分查找法都是非常通用的算法,可以在解决各种问题中使用。例如,双指针法可用于查找两个有序数组的交集,二分查找法可用于查找旋转有序数组中的最小值。

4. 有没有比双指针法和二分查找法更快的算法?

对于 LeetCode 167 问题,双指针法和二分查找法已经是时间复杂度最优的算法。但是,对于其他问题,可能存在更快的算法。

5. 我可以在哪里找到更多关于这些算法的信息?

网上有很多关于双指针法和二分查找法的资源。你可以参考 LeetCode 的讨论区、算法教程网站或书籍。