Leetcode刷题系列(python/java)之1. 两数之和(two-sum)

本系列为本人leetcode刷题之路2.0,将相关思考记录在此博客。欢迎批评指正。

1. 两数之和 two-sum

    • 题目理解
    • 解题思路
    • 解法1:暴力解法(双指针法).
      • python
      • java
    • 解法2:哈希表法.
      • python
      • java

题目理解

同样的元素不能重复使用(也就是不能自己加自己)
给定的数组中可能有相同的元素(比如 [3, 3, 4, 4, 5])

解题思路

  1. 暴力解法(双指针)
  2. hashmap
    (给面试官最好给最优解)?
    同时供参考:
    https://www.cxyxiaowu.com/2708.html

解法1:暴力解法(双指针法).

时间复杂度O(n^2),空间复杂度O(1)

python

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        # 解法1:暴力解法(双指针法)
        i = 0
        while (i<len(nums)):
            if i == len(nums) - 1:
                return "失败"
            r = target - nums[i]
            temps = nums[i+1:]
            for temp in temps:
                if r == temp:
                    return [i, temps.index(temp) + i + 1]
            i = i + 1

疑问:上面python程序中这步也申请了内存空间吗?:temps = nums[i+1:],对空间复杂度为O(1)有疑惑。

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        # 解法1:暴力解法(双指针法),时间复杂度O(n^2),空间复杂度O(1)
        length = len(nums)
        for i in range(length-1):
            for j in range(i+1, length):
                if nums[i] + nums[j] == target:
                    return [i,j]

疑问:还有一个python双指针,待写,其复杂度应该为O(nlogn)。见自己star的github/python。

java

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

解法2:哈希表法.

时间复杂度O(n),空间复杂度O(n).

python

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        hash_nums = {}
        for i in range(len(nums)):
            temp = target - nums[i] 
            if temp in hash_nums.keys():
                return [i, hash_nums[temp]]
            hash_nums[nums[i]] = i
class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        d = {}
        for i,num in enumerate(nums):
            if target - num in d:
                if d[target - num] != i:
                    return [d[target - num], i]
            d[num] = i

总结: 用了python的enumerate特性生成{索引:值}字典。

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        hash_nums = {}
        for index, num in enumerate(nums):
            another = target - num
            try:
                hash_nums[another]
                return [hash_nums[another], index]
            except KeyError:
                hash_nums[num] = index

总结:用了python的try、except,我都有点生疏了,有炫技成分。。
另外还有一个做法是哈希表每个list值后链接一个索引list,见我star的java/python。

java

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

总结:将数2与数1的index放到hash表里,遍历数组中的数,若该数在hash表里(则为数2),则返回哈希表中该数对应的value(数1index)和此时遍历的位置i(数2index)。花里胡哨,思路不常规,何必?用上面不是好好的。但是发现有好些人都这么做。

你可能感兴趣的:(数据结构与算法,leetcode,哈希,python,java)