[LeetCode] 1. Two Sum 两数之和

82 阅读2分钟

题目描述

Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target.

You may assume that each input would have exactly one solution, and you may not use the same element twice.

You can return the answer in any order.

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

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

你可以按任意顺序返回答案。

Example 1:

Input: nums = [2,7,11,15], target = 9
Output: [0,1]
Explanation: Because nums[0] + nums[1] == 9, we return [0, 1].

Example 2:

Input: nums = [3,2,4], target = 6
Output: [1,2]

Example 3:

Input: nums = [3,3], target = 6
Output: [0,1]

来源:力扣(LeetCode)

链接:leetcode.com/problems/tw…

题目解析

找出数组的两个下标,其对应的数组元素之和等于target

解题方法

方案一:暴力枚举

最简单的方法是两层遍历数组,第一层遍历记录第一个数组元素的下标,第二层遍历寻找与第一个数组元素之和等于target的其他的数组元素。

C#:

public class Solution {
    public int[] TwoSum(int[] nums, int target) {
        int len = nums.Length;
        for (int i = 0; i < len; i++) {
            for (int j = i + 1; j < len; j++) {
                if (nums[i] + nums[j] == target) {
                    return new int[] { i, j };
                }
            }
        }
        return null;
    }
}

Java:

class Solution {
    public int[] twoSum(int[] nums, int target) {
       int len = nums.length;
       for (int i = 0; i < len; i++) {
           for (int j = i + 1; j < len; j++) {
               if (nums[i] + nums[j] == target) {
                   return new int[] { i, j };
               }
           }
       }
       return null;
    }
}

Python:

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        leng = len(nums)
        for i in range(leng):
            for j in range(i + 1, leng):
                if (nums[i] + nums[j] == target):
                    return [ i, j ]
        return nill

复杂度分析

  • 时间复杂度:O(n^2),其中N是数组中的元素数量。最坏情况下数组中任意两个数都要被匹配一次。
  • 空间复杂度:O(1)。

方案二:哈希表

当遍历数组时,我们的目标是寻找元素target-x(x为当前的数组元素)。方案一的复杂度比较高,主要是因为对数组做了两次遍历,如果我们只遍历数组一次,并使用哈希表记录需要的数据就可以大大降低算法的复杂度。

C#:

public class Solution {
    public int[] TwoSum(int[] nums, int target) {
        for (int i = 0; i < nums.Count(); i++) 
        {
            int remaining = target - nums[i];
            int indexRight = Array.IndexOf(nums, remaining, i + 1);
            if (indexRight > 0)
            {
                return new int[] { i, indexRight };
            }            
        }
        return null;
    }
}

Java:

class Solution {
    public int[] twoSum(int[] nums, int target) {
       Map<Integer, Integer> map = new HashMap<>();
       for (int i = 0; i < nums.length; i++) {
           int complement = target - nums[i];
           if (map.containsKey(complement)) {
               return new int[] { i, map.get(complement)};
           }
           map.put(nums[i], i);
       }

       return null;
    }
}

Python:

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        hashmap = {}
        for i in range(len(nums)):
            complement = target - nums[i]
            if complement in hashmap:
                return [ i, hashmap[complement] ]
            hashmap[nums[i]] = i

复杂度分析

  • 时间复杂度:O(N),其中 N 是数组中的元素数量。对于每一个元素 x,我们可以 O(1) 地寻找 target - x。
  • 空间复杂度:O(N),其中 N 是数组中的元素数量。主要为哈希表的开销。

总结