CodeTop_1——两数之和(简单)——hash表

大家好,我是算法小白,我所选的题目从codetop挑选codetop,这是一个很好的刷算法题网站,适合即将面试或者准备面试大厂的老铁。
这一题是一道用空间代替时间的题(给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标)。
看到题目,首先会想到暴力解,双for循环来枚举所有解,得到结果返回,

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};
             }
          }
  }

当然这种解法最坏的情况每个数都要匹配一次,时间复杂度O(n^2)
所以内层的for循环可以进行一个优化,开辟一道内存hash表去替代。

for (int i = 0; i < nums.length; i++) {
     if(cache.containsKey(target - nums[i])){
         return new int[]{cache.get(target-nums[i]),i};
      }
      cache.put(nums[i],i);
  }

以值为key,索引为value,如果能从内存中找到target - nums[i]为key这条数据,那结果自然得到,
最终时间复杂度为O(n)。

如果在此基础上进行拓展,求三数之和怎么办?前面已经求出两数之和,我们可以把两数之和看出一个函数twoSum,三数之和不就是twoSum(target - num[i]),如果返回值不为空不就得出结果么,

public static int[] twoSum2(int[] nums, int target,int index) {
        Map<Integer,Integer> cache = new HashMap<>();
        for (int i = index; i < nums.length; i++) {
            if(cache.containsKey(target - nums[i])){
                return new int[]{cache.get(target-nums[i]),i};
            }
            cache.put(nums[i],i);
        }
        return null;
    }

    public static int[] threeSum(int[] nums, int target) {
        for (int i = 0; i < nums.length; i++) {
            int[] cur = twoSum(nums, target - nums[i], i + 1);
            if(cur!=null) {
                int[] array=new int[cur.length+1];
                for (int x = 0; x < cur.length; x++) {
                    array[x] = cur[x];
                }
                array[cur.length] = i;
                return array;
            }
        }
        return new int[]{0};
    }

N数之和怎么办?三数之和依赖两数之和,那N数之和自然依赖N-1数之和,这不就是一个递归么,我们只要把两数之和求出自然会求出N数之和,

public static int[] nSum(int[] nums, int n ,int index,int target) {
        if(n == 2){
            return twoSum2(nums, target, index);
        }else {
            for (int i = index; i < nums.length; i++) {
                int[] cur = nSum(nums, n-1, i + 1,target - nums[i]);
                if(cur!=null) {
                    int[] array=new int[cur.length+1];
                    for (int x = 0; x < cur.length; x++) {
                        array[x] = cur[x];
                    }
                    array[cur.length] = i;
                    return array;
                }
            }
        }

        return new int[]{0};
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值