给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
作为力扣的第一题当然是十分简单,暴力使用两层for循环查找也是不会超时的,当然它的时间复杂度比较高为O(n^2)
暴力做法
class Solution { public: vector<int> twoSum(vector<int>& nums, int target) { vector<int> ans; for(int i=0;i<nums.size();i++){ for(int j=i+1;j<nums.size();j++){ if(nums[i]+nums[j]==target){ ans.push_back(i); ans.push_back(j); return ans; } } } return ans; } };
这题可以作为双指针思想的最基础的映射
步骤:
1.先利用Arrays.sort将数组排好序,排序的时间复杂度为O(nlogn)
2.设一个指针i=0处于排序后的数组的头部,是一个j=n-1(n为数组的长度)即为数组的尾部
3.设一个变量add为i指向的数和j指向的数之和,即为nums[i]+nums[j]
4.我们对add的值和target进行比较,如果add大,说明我们需要让add变小,即让j向左移动。反之则让i向右移动。
5.当我们add等于target时跳出循环,通知接收nums【i】和nums【j】的值。(其实到这里双指针的思想就提现出来了,这样我们只用了O(n)的时间来遍历,但由于本题是输出数的下标,所以我们需要copy一份nums数组为arr,去遍历寻找原下标)
双指针做法
class Solution { public int[] twoSum(int[] nums, int target) { int n=nums.length; int[] arr=new int[n]; System.arraycopy(nums,0,arr,0,n); Arrays.sort(nums); int i=0; int j=n-1; int add=0; do{ add=nums[i]+nums[j]; if(add>target) j--; else if(add<target) i++; }while(add!=target); int a=nums[i]; int b=nums[j]; int[] str=new int[2]; for(int c=0;c<n;c++){ if(arr[c]==a){ str[0]=c; break; } } for(int d=0;d<n;d++){ if(arr[d]==b&&str[0]!=d){ str[1]=d; break; } } return str; } }
在第二个for循环寻找b的下标时,要考虑到a和b相等的情况,否则会让a与b的下标相等,所以需要附上srt【0】!=d的条件
总结:题目虽然简单,适合我们去理解双指针,但要考虑到各种特殊情况,代码量是比较大的,用来理解即可