zoukankan      html  css  js  c++  java
  • 两数之和

                              两数之和


    一、题目描述


    给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。

    你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。

    示例:

    给定 nums = [2, 7, 11, 15], target = 9

    因为 nums[0] + nums[1] = 2 + 7 = 9
    所以返回 [0, 1]

    二、题目分析


    给定输入是一个int类型的数组,一个目标值,目标输出是一个int类型的数组,数组中是相加为目标值的数的索引。

    三、算法


    ①暴力解法

     1 public static int[] twoSum1(int[] nums, int target) {
     2     int i;
     3     int j;
     4     for (i = 0; i < nums.length - 1; i++) {
     5         int temp1 = nums[i];
     6         for (j = i + 1; j < nums.length; j++) {
     7             if (nums[j] == target - temp1) {
     8                 return new int[] {i, j};
     9             } else {
    10                 continue;
    11             }
    12         }
    13     }
    14     return null;
    15         
    16 }

    第一重for循环固定了其中一个加数,第二重for循环用来寻找被加数,如果(目标值 - 加数)== (被加数),那么我们就找到了这两个数,之所以在最外层初始化 i 和 j ,是为了方便定位元素。我最开始还对目标值与加数的大小进行比对,如果加数比目标值大,就跳过本次循环,但是这种情况只在所有元素都为非负的情况下才有用,如果元素为负数就没用了...,所以后面就删掉了。这一种解法因为用到了双重for循环,所以时间复杂度为O(n2),空间复杂度为O(1)。

    ②使用map

     1 public static int[] twoSum2(int[] nums, int target) {
     2     Map<Integer, Integer> map = new HashMap<Integer, Integer>();
     3     for (int i = 0; i < nums.length; i++) {
     4         map.put(nums[i], i);
     5     }
     6     for (int i = 0; i < nums.length; i++) {
     7         int temp = target - nums[i];
     8         if (map.containsKey(temp) && map.get(temp) != i) {
     9             return new int[] {i, map.get(temp)};
    10         }
    11     }
    12     return null;
    13 }

    这道题目的核心就是确定一个数之后,在数组中寻找另外一个数及其索引,保持数组中的每个元素与其索引相互对应的最好方法是什么?哈希表。同样用到了双重for循环,第一重循环把数组中的元素存入ma中,以元素作为key,索引作为value,因为我们想要通过元素得到其对应的索引。第二重for循环首先确定一个加数nums[i],然后得到了被加数的值,使用map.containsKey()方法来判断map是否存在所要寻找的元素,map.get(temp)!= i 是因为题目要求两个整数,这里过滤掉输入数组中存在相同元素的情况。这种解法时间复杂度为O(n),因为对数组中的 n 个元素进行了循环,空间复杂度为O(n),因为使用了map来保存数组中的 n 个元素。

    ③一次循环

     1 public static int[] twoSum3(int[] nums, int target) {
     2     Map<Integer, Integer> map = new HashMap<Integer, Integer>();
     3     for (int i = 0; i < nums.length; i++) {
     4         int temp = target - nums[i];
     5         if (map.containsKey(temp)) {
     6             return new int[] {i, map.get(temp)};
     7         }
     8         map.put(nums[i], i);
     9     }
    10     return null;
    11 }

    首先确定加数nums[i],得到了被加数,在将数组中的元素插入map时先判断map是否已存在所寻找的值,如果有那就直接返回,没有再把它存入map,时间复杂度为O(n),空间复杂度为O(n)。

    四、说明


    解法均是在我的理解下给出,有参考官方解答。

    代码已上传github:

    https://github.com/Thinker-Mars/ByteDance/tree/master/sumOfTwoNumbers

    来源:力扣(LeetCode)

  • 相关阅读:
    Linux(Unix)时钟同步ntpd服务配置方法(转载)
    Linux SSH Publickey登录!
    三个最短路算法
    三个最短路算法
    最大子列和问题
    哈密尔顿环
    最小生成树应用解(超时)蓝桥杯2015初赛]灾后重建
    最小生成树应用解(超时)蓝桥杯2015初赛]灾后重建
    c++11的记录
    最大子列和问题
  • 原文地址:https://www.cnblogs.com/cone/p/11488997.html
Copyright © 2011-2022 走看看