英语角
distinct integers 不同整数 35
Spiral Matrix 螺旋矩阵 59
contiguously 连续地
scattered 分散的
programming context 编程上下文
traversal 遍历
Variants 变体(Circular and Doubly Linked Variants: circular linked lists& doubly linked lists
intersect 交叉
anagram 相同字母异序词
index 复数:indices
tuple 元组
triplet 三胞胎/三连音
quadruplet 四胞胎
ransom 赎金
ransom note 勒索信
APIs:
String API
1.s.length
2.s.charAt()
Array
1.Arrays.sort(arr);
2.Arrays.asList(arr)
List/Set/Map
List:
1.定义二维list;List<List<Integer>> res = new ArrayList<>();
Set:
1.size();
2.add(int);
3.contains()
4.将结果集合转为数组:
(1)resSet.stream().mapToInt(x -> x).toArray();
(2)另外申请一个数组存放setRes中的元素,最后返回数组
int[] arr = new int[resSet.size()];
int j = 0;
for(int i : resSet){
arr[j++] = i;
}
Map:
1.getOrderDefault(Object key,Integer default number):
key:要检索的键。
defaultValue:如果 Map 中不存在该键,则返回此默认值。
3.6 454. 4Sum II
Given four integer arrays nums1, nums2, nums3, and nums4 all of length n, return the number of tuples (i, j, k, l) such that:
0 <= i, j, k, l < n
nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0
public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
int count = 0;
Map<Integer,Integer> map = new HashMap<Integer,Integer>();
for(int i : nums1){
for(int j:nums2){
int sum = i+j;
map.put(sum,map.getOrDefault(sum,0)+1);
}
}
for(int i : nums3){
for(int j:nums4){
// int sum = -(i+j);
// if(map.containsKey(sum)){
// count += map.get(sum);
// }
//可简化为:返回key=-(i+j)对应的value,如果没有,则返回0
count += map.getOrDefault(0-(i+j),0);
}
}
return count;
}
3.7 383. Ransom Note
Given two strings ransomNote and magazine, return true if ransomNote can be constructed by using the letters from magazine and false otherwise.
Each letter in magazine can only be used once in ransomNote.
思路和anagram差不多
public boolean canConstruct(String ransomNote, String magazine) {
int[] arr = new int[26];
for (int i = 0; i < magazine.length(); i++) {
arr[magazine.charAt(i)-'a']++;
}
for (int i = 0; i < ransomNote.length(); i++) {
arr[ransomNote.charAt(i)-'a']--;
}
for(int i : arr){
if(i < 0) return false;
}
return true;
}
3.8 15. 3Sum
Given an integer array nums, return all the triplets [nums[i], nums[j], nums[k]] such that i != j, i != k, and j != k, and nums[i] + nums[j] + nums[k] == 0.
Notice that the solution set must not contain duplicate triplets.
哈希法不便于去重,用双指针法。
审题!!这道题我一开始理解错了,以为是三个数组,分别需要从三个数组中找到下标不同的满足条件的三个元素。审题很重要!!!
自己写的时候犯了一些错误,主要集中在有结果后的部分。
得到结果后需要做三件事:去重left,去重right,left、right往前进一步。如果去重后忘记继续走,那么循环将无法结束。
并且得到结果后的部分都是写在sum==0条件的执行语句中的。不然会导致left/right在sum!=0的时候重复往下走,可能会导致漏解(比如leetcode隐藏测试{-1,-1,0,1}.
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
Arrays.sort(nums);
for (int i = 0; i < nums.length; i++) {
//剪枝
if(nums[i] > 0) return res;
//对nums[i]去重
if(i > 0 && nums[i] == nums[i-1]) continue;
int left = i+1;
int right = nums.length-1;
while (left < right){
//先返回一个结果
int sum = nums[i] + nums[left] + nums[right];
if(sum > 0){
right--;
}else if(sum < 0){
left++;
}else{
res.add(Arrays.asList(nums[i],nums[left],nums[right]));
//这后面是得到一个结果后做的操作:去重left,去重right,left、right往前进一步
//再去重left right
while (left < right && nums[right] == nums[right-1]){
right--;
}
while (left < right && nums[left] == nums[left+1]){
left++;
}
//去重结束以后往下走!!!这步不能忘
left++;
right--;
}
}
}
return res;
}
编写测试类的时候顺便复习了一下三种遍历方法中的iterator遍历和增强for循环遍历,并且这是二重list:
public static void main(String[] args) {
threeSumNoRepeat t = new threeSumNoRepeat();
int[] ints = {-1,-1,1,0};
List<List<Integer>> res = t.threeSum(ints);
//遍历方法1:增强for循环
for (List<Integer> innerList : res) {
System.out.print("[");
for (Integer num : innerList) {
System.out.print(num + (innerList.indexOf(num) < innerList.size() - 1 ? ", " : ""));
}
System.out.println("]");
}
//遍历方法2:iterator
// Iterator<List<Integer>> outerIterator = res.iterator();
// while (outerIterator.hasNext()) {
// List<Integer> innerList = outerIterator.next();
// Iterator<Integer> innerIterator = innerList.iterator();
//
// System.out.print("[");
// while (innerIterator.hasNext()) {
// Integer num = innerIterator.next();
// System.out.print(num + (innerIterator.hasNext() ? ", " : ""));
// }
// System.out.println("]");
// }
}
3.9 18. 4Sum
Given an array nums of n integers, return an array of all the unique quadruplets [nums[a], nums[b], nums[c], nums[d]] such that:
0 <= a, b, c, d < n
a, b, c, and d are distinct.
nums[a] + nums[b] + nums[c] + nums[d] == target
You may return the answer in any order.
这题写的时候错误点在于:int sum = nums[i] + nums[j] + nums[left] + nums[right];应该写在while(left<right)执行条件内,不然会导致left下标溢出。
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> res = new ArrayList<>(); Arrays.sort(nums); for (int i = 0; i < nums.length ; i++) { //一级剪枝+一级去重 //if(nums[i] > target && (nums[i]>=0 || target>0)) return res; if(nums[i] > 0 && nums[i] > target) return res; if(i>0 && nums[i] == nums[i-1]) continue; for (int j = i+1; j < nums.length; j++) { //二级剪枝+二级去重 //if(nums[i]+nums[j] > target && (nums[i]+nums[j]>=0 || target>0)) return res; if(nums[i]+nums[j] > 0 && nums[i]+nums[j] > target) return res; //因为后面要比较j-1,所以要保证j > i+1 if(j > i+1 && nums[j] == nums[j-1]) continue; int left = j+1; int right = nums.length-1; while(left<right){ int sum = nums[i] + nums[j] + nums[left] + nums[right]; if (sum<target){ left++; }else if(sum>target){ right--; }else{ res.add(Arrays.asList(nums[i],nums[j],nums[left],nums[right])); while(left<right && nums[left] == nums[left+1]) left++; while(left<right && nums[right] == nums[right-1]) right--; left++; right--; } } } } return res;
}