LeetCode 热题 100---01~03 ------->哈希
第一题 两数之和
思路
最直接的理解就是 找出两个数的和等于目标数 这两个数可以相同 但是不能是同一个数字(从数组上理解就是内存上不是同一位置)
解法一:暴力法
暴力解万物 按照需求 我们需要将数组的任意不同位置的数两两相加 再去判断是否等于目标数target 那么很显然 利用for循环的嵌套 第一层for循环从头遍历到尾 表示第一个数字 ;第二个数从第一个数的后一位置开始遍历到尾部,表示第二个数字
因为题目中明确说明了每种输入只会对应一个答案 所以找到之后就可以直接返回了
那么对应的代码就是
class Solution {
public int[] twoSum(int[] nums, int target) {
int n = nums.length;
for (int i = 0; i < n; ++i) {
for (int j = i + 1; j < n; ++j) {
if (nums[i] + nums[j] == target) {
return new int[]{i, j};
}
}
}
return new int[0];
}
}
时间复杂度为O(N^2)
解法二:双指针法
上述时间复杂度之所以高 是因为我们查找第二个数采用的也是循环 就导致了循环的嵌套,如果想降低时间复杂度,那么就需要降低第二个数的查找时间
其实这个思路也比较简单 就是我们先将数组进行排序 保证从小到大/从大到小排序(这里我们排从小到大),那么 我们就可以最开始从数组最左侧A和最右侧B的两个数据开始相加得到sum 如果sum>target 那么说明我们需要讲两个加数变小,已知一个加数A已经是最小 那么只能让B往前走一位从而减小数据(当然 如果倒数第二个数据和最后一个数据等大 自然得出来的结果还是会大于target 但是不妨碍我们继续判断),反之 如果sum<target 那么就需要增大加数,只有加数A能够增大 所以就需要将加数A向右移动一位,依此类推,直到找到数据
class Solution {
public int[] twoSum(int[] nums, int target) {
ArrayList<Integer> list=new ArrayList<>();
for (int num : nums) {
list.add(num);
}
int[] dest = Arrays.copyOf(nums, nums.length);
Arrays.sort(dest);
int slow=0;int fast=nums.length-1;
while(slow!=fast){
int sum=dest[slow]+dest[fast];
if(sum==target){
int i = list.indexOf(dest[slow]);
int j = list.lastIndexOf(dest[fast]);
return new int[]{i,j};