14天刷爆LeetCode算法学习计划——Day03 双指针(2)

简介: 当我们的sum 比 target(要求的和)大的话,由于数组按照递增的顺序,既然此时left指向的已经是数组最小值了,那么只能将right指向的值变得更小,即 right的值减1

一、前言


盲目刷题只会让自己心态爆炸,所以本期14天算法学习计划,也是LeetCode上的 *[算法]*学习计划,在本专栏的每一篇文章都会整理每一天的题目并给出详细题解,以及知识点的整理


二、知识点


戳下方链接查看⬇⬇⬇


14天刷爆LeetCode算法学习计划——Day02双指针(1)


三、LeetCode167. 两数之和 II - 输入有序数组


1.题目


LeetCode167. 两数之和 II -输入有序数组

给你一个下标从 1 开始的整数数组 numbers ,该数组已按 非递减顺序排列 ,请你从数组中找出满足相加之和等于目标数 target 的两个数。如果设这两个数分别是numbers[index1] 和 numbers[index2] ,则 1 <= index1 < index2 <= numbers.length 。


以长度为 2 的整数数组 [index1, index2] 的形式返回这两个整数的下标 index1 和 index2。

你可以假设每个输入 只对应唯一的答案 ,而且你 不可以 重复使用相同的元素。

你所设计的解决方案必须只使用常量级的额外空间。


示例 1:

输入:numbers = [2,7,11,15], target = 9

输出:[1,2]

解释:2 与 7 之和等于目标数 9 。因此index1 = 1, index2 = 2 。返回 [1, 2] 。


示例 2:

输入:numbers = [2,3,4], target = 6

输出:[1,3]

解释:2 与 4 之和等于目标数 6 。因此index1 = 1, index2 = 3 。返回 [1, 3] 。


示例 3:

输入:numbers = [-1,0], target = -1

输出:[1,2]

解释:-1 与 0 之和等于目标数 -1 。因此index1 = 1, index2 = 2 。返回 [1, 2] 。


2.解题思路(含图)


  • 我们可以定义左右指针,并将左右指针指向的值的和赋值给一个变量sum
  • 当我们的 sum 比 targer(要求的和)小 的话,由于数组按照递增的顺序,既然此时right指向的已经是数组最大值了,那么只能将left指向的值变得更大,即 left的值加1


129cbf4dd2c54cc782b9f198e4b631d1.png


  • 当我们的sum 比 target(要求的和)大的话,由于数组按照递增的顺序,既然此时left指向的已经是数组最小值了,那么只能将right指向的值变得更小,即 right的值减1

e72b84fa5642451a862800313651e6c9.png


  • 重复操作,直至 sum = target


013c916db77c4328bcfe7dc636f7f3ce.png


3.注意事项


  • 数组的下标值是从1开始记录的,所以在输出时 left 和 right 的值要加1


  • 由于此时要输出的是数组形式,所以返回值不能是一个值,而要是数组,即 return new int[] {left + 1,right + 1}


4.代码实现


class Solution {
    public int[] twoSum(int[] numbers, int target) {
      //定义左指针
        int left = 0;
        //定义右指针
        int right = numbers.length - 1;
        //求下标值
        while(left < right){
          //用变量sum接收左右指针指向元素的和,使代码更简洁
            int sum = numbers[left] + numbers[right];
            //指针指向元素的和比目标数大
            if(sum > target){
                right--;
            }
            //指针指向元素的和比目标数小
            else if(sum < target){
                left++;
            }
            //指针指向元素的和比目标数相等
            else{
              //以数组形式返回下标值
                return new int[] {left+1,right+1};
            }
        }
        //如果找不到,就返回元素都是-1的数组
        return new int[] {-1,-1};
    }
}


5.验证代码


f0796a5fc5bf4b9c974d34d499981f2f.png



6.时间复杂度和空间复杂度


  • 时间复杂度:O(n)


  • 空间复杂度:O(1)


7.其它解法


1️⃣二分查找


class Solution {
    public int[] twoSum(int[] numbers, int target) {
        for (int i = 0; i < numbers.length; ++i) {
            int low = i + 1, high = numbers.length - 1;
            while (low <= high) {
                int mid = (high - low) / 2 + low;
                if (numbers[mid] == target - numbers[i]) {
                    return new int[]{i + 1, mid + 1};
                } else if (numbers[mid] > target - numbers[i]) {
                    high = mid - 1;
                } else {
                    low = mid + 1;
                }
            }
        }
        return new int[]{-1, -1};
    }
}


  • 时间复杂度:O(nlogn)


  • 空间复杂度:O(1)


2️⃣暴力求解(我的第一次尝试)


class Solution {
    public int[] twoSum(int[] numbers, int target) {
        int[] result = new int[2];
        for(int index1 =0; index1 <= numbers.length-  1; index1++){
            for(int index2 = index1+1; index2 <= numbers.length - 1; index2++){
                if(numbers[index1] + numbers[index2] == target){
                    result[0] = index1 + 1;
                    result[1] = index2 + 1;
                }
            }
        }
        return result;
    }
}  


四、结语


本题的暴力解法应该是大家的第一想法,但是如何优化代码,并降低时间复杂度就需要用到算法了,本题一定要明白双指针的含义才能在下次看到题目时不会再只用暴力求解的方式去解决问题了

相关文章
|
2月前
|
算法
Leetcode 初级算法 --- 数组篇
Leetcode 初级算法 --- 数组篇
46 0
|
1月前
|
存储 算法 Java
leetcode算法题-有效的括号(简单)
【11月更文挑战第5天】本文介绍了 LeetCode 上“有效的括号”这道题的解法。题目要求判断一个只包含括号字符的字符串是否有效。有效字符串需满足左括号必须用相同类型的右括号闭合,并且左括号必须以正确的顺序闭合。解题思路是使用栈数据结构,遍历字符串时将左括号压入栈中,遇到右括号时检查栈顶元素是否匹配。最后根据栈是否为空来判断字符串中的括号是否有效。示例代码包括 Python 和 Java 版本。
|
2月前
|
算法
每日一道算法题(Leetcode 20)
每日一道算法题(Leetcode 20)
35 2
|
4月前
|
算法 Java
LeetCode经典算法题:矩阵中省份数量经典题目+三角形最大周长java多种解法详解
LeetCode经典算法题:矩阵中省份数量经典题目+三角形最大周长java多种解法详解
57 6
|
4月前
|
人工智能 算法 Java
LeetCode经典算法题:井字游戏+优势洗牌+Dota2参议院java解法
LeetCode经典算法题:井字游戏+优势洗牌+Dota2参议院java解法
54 1
|
4月前
|
存储 算法 Java
LeetCode经典算法题:预测赢家+香槟塔java解法
LeetCode经典算法题:预测赢家+香槟塔java解法
68 1
|
4月前
|
存储 算法 Java
LeetCode经典算法题:二叉树遍历(递归遍历+迭代遍历+层序遍历)以及线索二叉树java详解
LeetCode经典算法题:二叉树遍历(递归遍历+迭代遍历+层序遍历)以及线索二叉树java详解
84 0
|
4月前
|
算法 Java
LeetCode初级算法题:子数组最大平均数+二叉树的最小深度+最长连续递增序列+柠檬水找零
LeetCode初级算法题:子数组最大平均数+二叉树的最小深度+最长连续递增序列+柠檬水找零
45 0
|
4月前
|
算法 Java
LeetCode初级算法题:环形链表+排列硬币+合并两个有序数组java解法
LeetCode初级算法题:环形链表+排列硬币+合并两个有序数组java解法
59 0
|
4月前
|
存储 算法 Java
LeetCode初级算法题:两数之和+斐波拉契数列多种java解法
LeetCode初级算法题:两数之和+斐波拉契数列多种java解法
49 0