1.两数之和
第一眼看见这道题思路就是双层循环来遍历,对每个元素nums[i], 去遍历找数组中是否存在元素 == target - nums[i]:
class Solution {
public int[] twoSum(int[] nums, int target) {
int[] ret = new int [2];
for(int i = 0; i < nums.length; ++i){
for (int j = i + 1; j < nums.length; ++j){
if (nums[i] + nums[j] == target){
ret[0] = i;
ret[1] = j;
}
}
}
return ret;
}
}
但这样的操作时间复杂度很大, 达到了O(n^2), 显然不符合题意。可以通过增加空间复杂度的方式来降低时间复杂度,通过一个哈希表的方式:
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(target - nums[i])){
return new int[] {i, map.get(target - nums[i])};
}
map.put(nums[i], i);
}
return new int[] {-1, -1};
}
}
哈希表中每个key是数组元素本身,value是数组元素的下标。在遍历每个元素时,首先去check一下哈希表中是否存在target - nums[i], 如果存在,则直接返回结果。如果不存在,就把当前元素放入到哈希表当中去。
49.字母异位词分组
这道题其实很奇怪,本质就是将一个字符串无损压缩起来,最简单的方式就是排序,或者用官方题解那种对26个字母出现次数计数的形式。个人认为不应该算medium难度的题目:
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
Map<String, List<Integer>> map = new HashMap<>();
for(int i =0; i < strs.length; ++i){
char[] chars = strs[i].toCharArray();
Arrays.sort(chars);
String sorted = new String(chars);
if (map.containsKey(sorted)){
map.get(sorted).add(i);
}else{
map.put(sorted, new ArrayList<>(Arrays.asList(i)));
}
}
List<List<String>> ret = new ArrayList<>();
for(String key: map.keySet()){
List<String> tmp = new ArrayList<>();
for (Integer idx: map.get(key)){
tmp.add(strs[idx]);
}
ret.add(tmp);
}
return ret;
}
}
128.最长连续序列
这道题的描述有点隐晦,相同的数字只能用其中一个, 比如[0, 0, 1, 2, 3]最后的连续序列就是[0, 1, 2, 3], 而不是[0, 0, 1, 2, 3]. 然后解题思路还是如何构建序列长度的映射,我当时的想法是,序列长度只与该序列第一个数字有关,即第一个数字开始的长度为k。而这道题又要找最长的序列,因此起始元素应该是最小,因此对于每个数组元素nums[i], 如果nums[i] - 1在数组中,那么nums[i]就不可能是最长序列的起始元素,反之则有可能。
另外就是记得刚开始做一次去重,不然会超时…
class Solution {
public int longestConsecutive(int[] nums) {
int len = nums.length;
int ret = 0;
Set<Integer> numsSet = new HashSet<>();
for(int i = 0; i < len; ++i){
numsSet.add(nums[i]);
}
for(int num: numsSet){
int current = num;
if (numsSet.contains(current - 1)) continue;
int currentLen = 1;
while(numsSet.contains(current + 1)){
current ++;
currentLen += 1;
}
ret = Math.max(ret, currentLen);
}
return ret;
}
}