day07 打卡454. 四数相加 II 383. 赎金信 15. 三数之和 18. 四数之和
day07 打卡454. 四数相加 II 383. 赎金信 15. 三数之和 18. 四数之和
454. 四数相加 II
1.看了视频讲解后写的。使用map,记住nums1和nums2的相加,再到nums3和nums4中寻找相加等于0的组合。
class Solution {
public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
if (nums1 == null || nums1.length == 0) {
return 0;
}
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0 ; i<nums1.length ; i++) {
for (int j = 0 ; j<nums2.length ; j++) {
int sum = nums1[i] + nums2[j];
if (map.containsKey(sum)) {
Integer count = map.get(sum);
map.put(sum, count+1);
} else {
map.put(sum, 1);
}
}
}
int result = 0;
for (int i = 0 ; i<nums3.length ; i++) {
for (int j = 0 ; j<nums4.length ; j++) {
int sum = 0 - nums3[i] - nums4[j];
if (map.containsKey(sum)) {
Integer count = map.get(sum);
result += count;
}
}
}
return result;
}
}
383. 赎金信
1.这道题目跟昨天的有效的字母异位词是一样的思路,记住不同字母对应的次数。再次循环减去次数,如果次数不足,就返回false。
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
boolean result = true;
int[] record = new int[26];
for (int i = 0 ; i<magazine.length() ; i++) {
char c = magazine.charAt(i);
record[c - 'a']++;
}
for (int i = 0 ; i<ransomNote.length() ; i++) {
char c = ransomNote.charAt(i);
if (record[c - 'a'] <= 0) {
result = false;
break;
} else {
record[c - 'a']--;
}
}
return result;
}
}
15. 三数之和
1.超出时间限制。思路:循环两次,使用map,key为两次相加,value记住i与j。再循环一次,找到相加为0的k,判断i、j、k是否都不想等,再调用existSameList判断result中是否已经有相同的list了,如果没有,加入result中。
但是当nums数量很多的时候,existSameList消耗太多时间了,每一次都要全部便利再是否一致。
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
Map<Integer, List<Integer>> map = new HashMap<>();
for (int i = 0 ; i<nums.length-1 ; i++) {
for (int j = i+1; j<nums.length ; j++) {
int sum = nums[i] + nums[j];
List<Integer> list = new ArrayList<>();
if (map.containsKey(sum)) {
list = map.get(sum);
list.add(i);
list.add(j);
map.put(sum, list);
} else {
list.add(i);
list.add(j);
map.put(sum, list);
}
}
}
for (int k = 0 ; k<nums.length ; k++) {
if (map.containsKey(0-nums[k])) {
List<Integer> list = map.get(0-nums[k]);
for (int index = 0 ; index+1<list.size() ; index = index+2) {
Integer i = list.get(index);
Integer j = list.get(index+1);
if (i!=j && i!=k && j!=k) {
List<Integer> resultList = new ArrayList<>();
resultList.add(nums[i]);
resultList.add(nums[j]);
resultList.add(nums[k]);
if (!existSameList(result, resultList)) {
result.add(resultList);
}
}
}
}
}
return result;
}
public boolean existSameList(List<List<Integer>> list, List<Integer> add) {
if (list.size() == 0) return false;
boolean result = true;
add.sort((x,y) -> x-y);
for (List<Integer> l: list) {
l.sort((x,y) -> x-y);
result = true;
for (int i = 0 ; i<l.size() ; i++) {
if (l.get(i) != add.get(i)) {
result = false;
break;
}
}
if (result) {
break;
}
}
return result;
}
}
2.去看视频了,使用双指针法。
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
// 排序
Arrays.sort(nums);
// 双指针
int left = 0;
int right = 0;
for (int i = 0 ; i<nums.length ; i++) {
if (nums[i] > 0) return result;
// 去重i
if (i > 0 && nums[i] == nums[i-1]) continue;
left = i+1;
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 {
// 找到了等于0的三元组
List<Integer> list = new ArrayList<>();
list.add(nums[i]);
list.add(nums[left]);
list.add(nums[right]);
result.add(list);
// 去重left
while(left<right && nums[left] == nums[left+1]) left++;
// 去重rigjt
while(left<right && nums[right] == nums[right-1]) right--;
left++;
right--;
}
}
}
return result;
}
}
18. 四数之和
1.直接看视频后,写代码的。
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> result = new ArrayList<>();
int left, right;
// 排序
Arrays.sort(nums);
for (int i = 0 ; i<nums.length ; i++) {
// 对i进行剪枝
if (nums[i] > 0 && nums[i] > target) {
return result;
}
// 对i去重
if (i>0 && nums[i] == nums[i-1]) {
continue;
}
for (int j = i+1 ; j<nums.length; j++) {
// 对j去重
if (j>i+1 && nums[j] == nums[j-1]) {
continue;
}
left = j+1;
right = nums.length-1;
while (left<right) {
// 防止int溢出
long sum = (long) nums[i] + nums[j] + nums[left] + nums[right];
if (sum > target) {
right--;
} else if (sum < target) {
left++;
} else {
// 将符合条件的四元组加入result
List<Integer> list = new ArrayList<>();
list.add(nums[i]);
list.add(nums[j]);
list.add(nums[left]);
list.add(nums[right]);
result.add(list);
// 对left去重
while (left<right && nums[left] == nums[left+1]) left++;
// 对right去重
while (left<right && nums[right] == nums[right-1]) right--;
left++;
right--;
}
}
}
}
return result;
}
}
总结
哈希表主要使用的三种数据结构是:数组、set、map。
关键字就是看到 一个元素是否出现集合里
使用场景:
数组:限制数值的大小
set:没有限制数值的大小,存的值独一无二,只存一个
map:需要多存多个

浙公网安备 33010602011771号