454.四数相加II
题目链接/文章讲解/视频讲解:四数相加II
以下知识点来自菜鸟教程:Java HashMap getOrDefault() 方法 | 菜鸟教程
getOrDefault()
方法:
getOrDefault()
方法获取指定key
对应对value
,如果找不到key
,则返回设置的默认值。
getOrDefault()
方法的语法为:
hashmap.getOrDefault(Object key, V defaultValue)
**注:**hashmap 是 HashMap 类的一个对象。
参数说明:
key
- 键defaultValue
- 当指定的key
并不存在映射关系中,则返回的该默认值返回值
返回 key 相映射的的 value,如果给定的 key 在映射关系中找不到,则返回指定的默认值。
class Solution {
public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
Map<Integer, Integer> map = new HashMap<>();
int res = 0;
for (int i : nums1) {
for (int j : nums2) {
int sum = i + j;
// 将和及其出现的次数存入哈希表中
// 如果 sum 已经存在于 map 中,则将其值加 1,否则将其值设为 1
map.put(sum, map.getOrDefault(sum, 0) + 1);
}
}
for (int i : nums3) {
for (int j : nums4) {
// 计算当前两个元素的和的负值(即 0 - i - j)
// 在哈希表中查找该负值,并将其对应的值(即该和出现的次数)加到结果中
// 如果该负值不存在于 map 中,则返回默认值 0
res += map.getOrDefault(0 - i - j, 0);
}
}
return res;
}
}
383.赎金信
题目链接/文章讲解:赎金信
方法和 有效的字母异位词 类似。其实可以直接用数组,为了练习 HashMap
所以用了 map
的写法:
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
Map<Integer, Integer> map = new HashMap<>();
for (char i : magazine.toCharArray()) {
map.put(i - 'a', map.getOrDefault(i - 'a', 0) + 1);
}
for (char j : ransomNote.toCharArray()) {
map.put(j - 'a', map.getOrDefault(j - 'a', 0) - 1);
}
for (int k : map.values()) {
if (k < 0) {
return false;
}
}
return true;
}
}
15.三数之和
题目链接/文章讲解/视频讲解:三数之和
双指针
- 先对数组进行排序;
i
用来遍历数组;- 计算
sum = nums[i]+nums[left]+nums[right]
,若sum<0
,则left
指针右移;若sum>0
,则right
指针左移; - 在移动过程中进行判重,若
nums[left]==nums[left+1]
则跳过left+1
,若nums[right]==nums[right-1]
则跳过nums[right-1]
; i
在移动过程中也要判重,如果nums[i]==nums[i-1]
,则跳过i
.
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
Arrays.sort(nums);
for (int i = 0; i < nums.length; i++) {
int left = i + 1;
int right = nums.length - 1;
if (nums[i] > 0) {
return result;
}
if (i > 0 && nums[i] == nums[i - 1]) {
continue;
}
while (left < right) {
if (nums[i] + nums[left] + nums[right] < 0) {
left++;
} else if (nums[i] + nums[left] + nums[right] > 0) {
right--;
} else {
result.add(Arrays.asList(nums[i], 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 result;
}
}
18.四数之和
题目链接/文章讲解/视频讲解: 四数之和
双指针
感觉思路是 两数之和
和 三数之和
的结合,
- 用
i
和j
两个循环遍历数组,balance = target - nums[i] - nums[j]
; - 定义两个指针
left = j+1
和right = length-1
,sum2 = nums[left] + nums[j]
- 将
sum2
和balance
比较,如果sum2<balance
,left
指针右移,如果sum2>balance
,right
指针左移; - 判重的思路和上一题
三数之和
一样,不多赘述.
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> result = new ArrayList<>();
Arrays.sort(nums);
int length = nums.length;
for (int i = 0; i < length - 3; i++) {
// 避免重复
if (i > 0 && nums[i] == nums[i - 1]) {
continue;
}
for (int j = i + 1; j < length - 2; j++) {
// 避免重复
if (j > i + 1 && nums[j] == nums[j - 1]) {
continue;
}
long balance = (long) target - nums[i] - nums[j];
int left = j + 1;
int right = length - 1;
while (left < right) {
long sum2 = (long) nums[left] + nums[right];
if (sum2 < balance) {
left++;
} else if (sum2 > balance) {
right--;
} else {
result.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 result;
}
}