两数之和

力扣地址

题目描述

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

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。

示例:

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

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

题目解答

这道题使用hashset就是用空间换时间。

1
2
3
4
5
6
7
8
9
10
from typing import List


class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
hashset = {}
for i in range(len(nums)):
if hashset.get(target - nums[i]) is not None:
return [hashset.get(target-nums[i]),i]
hashset[nums[i]] = i
1
2
3
4
5
6
7
8
9
10
11
public int[] twoSum(int[] nums, int target) {
HashMap<Integer, Integer> indexForNum = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
if (indexForNum.containsKey(target - nums[i])) {
return new int[]{indexForNum.get(target - nums[i]), i};
} else {
indexForNum.put(nums[i], i);
}
}
return null;
}

存在重复元素

力扣地址

题目描述

给定一个整数数组,判断是否存在重复元素。

如果任意一值在数组中出现至少两次,函数返回 true 。如果数组中每个元素都不相同,则返回 false

示例 1:

1
2
输入: [1,2,3,1]
输出: true

示例 2:

1
2
输入: [1,2,3,4]
输出: false

示例 3:

1
2
输入: [1,1,1,3,3,4,3,2,4,2]
输出: true

题目解答

将所有元素添加进set,若哈希表长度小于数组长度即有重复元素

1
2
3
4
5
6
from typing import List


class Solution:
def containsDuplicate(self, nums: List[int]) -> bool:
return True if len(set(nums)) < len(nums) else False
1
2
3
4
5
6
7
public boolean containsDuplicate(int[] nums) {
Set<Integer> set = new HashSet<>();
for (int num : nums) {
set.add(num);
}
return set.size() < nums.length;
}

最长和谐子序列

力扣地址

题目描述

和谐数组是指一个数组里元素的最大值和最小值之间的差别正好是1。

现在,给定一个整数数组,你需要在所有可能的子序列中找到最长的和谐子序列的长度。

示例 1:

1
2
3
输入: [1,3,2,2,5,2,3,7]
输出: 5
原因: 最长的和谐数组是:[3,2,2,2,3].

题目解答

需要注意的是和谐数组不一定是原数组的子序列

1
2
3
4
5
6
7
8
9
10
11
12
13
from typing import List


class Solution:
def findLHS(self, nums: List[int]) -> int:
hashSet = {}
for num in nums:
hashSet[num] = hashSet.get(num, 0) + 1
long = 0
for i in hashSet:
if i + 1 in hashSet:
long = max(long, hashSet[i] + hashSet[i + 1])
return long
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public int findLHS(int[] nums) {
Map<Integer, Integer> countForNum = new HashMap<>();
for (int num : nums) {
countForNum.put(num, countForNum.getOrDefault(num, 0) + 1);
}
int longest = 0;
for (int num : countForNum.keySet()) {
if (countForNum.containsKey(num + 1)) {
longest = Math.max(longest, countForNum.get(num + 1) + countForNum.get(num));
}
}
return longest;
}
public boolean containsDuplicate(int[] nums) {
Set<Integer> set = new HashSet<>();
for (int num : nums) {
set.add(num);
}
return set.size() < nums.length;
}

最长连续子序列

力扣地址

题目描述

给定一个未排序的整数数组,找出最长连续序列的长度。

要求算法的时间复杂度为 O(n)

示例:

1
2
3
输入: [100, 4, 200, 1, 3, 2]
输出: 4
解释: 最长连续序列是 [1, 2, 3, 4]。它的长度为 4。

题目解答

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from typing import List


class Solution:
def longestConsecutive(self, nums: List[int]) -> int:
hashSet = set(nums)
long = 0
for i in hashSet:
if i - 1 in hashSet: # 判断是不是首个数字
continue
curLong = 1
while i + 1 in hashSet:
curLong += 1
i += 1
long = max(long, curLong)
return long
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public int longestConsecutive(int[] nums) {
Map<Integer, Integer> countForNum = new HashMap<>();
for (int num : nums) {
countForNum.put(num, 1);
}
for (int num : nums) {
forward(countForNum, num);
}
return maxCount(countForNum);
}

private int forward(Map<Integer, Integer> countForNum, int num) {
if (!countForNum.containsKey(num)) {
return 0;
}
int cnt = countForNum.get(num);
if (cnt > 1) {
return cnt;
}
cnt = forward(countForNum, num + 1) + 1;
countForNum.put(num, cnt);
return cnt;
}

private int maxCount(Map<Integer, Integer> countForNum) {
int max = 0;
for (int num : countForNum.keySet()) {
max = Math.max(max, countForNum.get(num));
}
return max;
}