本系列为本人leetcode刷题之路2.0,将相关思考记录在此博客。欢迎批评指正。
题目理解
同样的元素不能重复使用(也就是不能自己加自己)
给定的数组中可能有相同的元素(比如 [3, 3, 4, 4, 5])
解题思路
- 暴力解法(双指针)
- 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)。花里胡哨,思路不常规,何必?用上面不是好好的。但是发现有好些人都这么做。