哈希表
四数相加II
- 暴力法:四重for循环
- 哈希表: 先用两层for循环将两个数组中的元素和记录在哈希表中, 然后再将另外两个数组用for循环遍历, 求其和的负数是否在哈希表中, 记录个数
代码:
class Solution {
public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
int n = nums1.length;
HashMap<Integer, Integer> map = new HashMap<>();
for(int i=0; i<n; i++){
for(int j=0; j<n; j++){
int sum = nums1[i] + nums2[j];
map.put(sum, map.getOrDefault(sum, 0) + 1);
}
}
int ans = 0;
for(int i=0; i<n; i++){
for(int j=0; j<n; j++){
int sum = nums3[i] + nums4[j];
if(map.containsKey(-sum)){
ans += map.get(-sum);
}
}
}
return ans;
}
}
383 赎金信
- 先统计 ransomNote 里面的字符个数, 记录在哈希表中
- 然后遍历 magazine, 如果哈希表中有, 就将其个数-1
- 最后再遍历哈希表, 若里面字符个数 > 0, 则代表不够组成 ransomNote, 返回false
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
HashMap<Character, Integer> map = new HashMap<>();
for(int i=0; i<ransomNote.length(); i++){
char c = ransomNote.charAt(i);
map.put(c, map.getOrDefault(c, 0) + 1);
}
for(int i=0; i<magazine.length(); i++){
char c = magazine.charAt(i);
if(map.containsKey(c)){
map.put(c, map.get(c) - 1);
}
}
for(char c : map.keySet()){
if(map.get(c) > 0) return false;
}
return true;
}
}
15.三数之和
排序+双指针法
先排序,然后固定一个数,另外两个数用双指针寻找
代码:
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
Arrays.sort(nums);
List<List<Integer>> list = new ArrayList<>();
for(int i=0; i<nums.length && nums[i] <= 0; i++){
// 去重
if(i > 0 && nums[i] == nums[i-1]) continue;
int l = i + 1, r = nums.length - 1;
while(l < r) {
int sum = nums[i] + nums[l] + nums[r];
if(sum < 0) {
l++;
}else if(sum > 0) {
r--;
}else {
list.add(Arrays.asList(nums[i], nums[l], nums[r]));
while(l < r && nums[l] == nums[l+1]) l++;
while(l < r && nums[r] == nums[r-1]) r--;
// 移动双指针
l++; r--;
}
}
}
return list;
}
}
18.四数之和
- 参照三数之和
- 用两层for循环固定两个数字
- 然后其余两个数字用双指针寻找, 用排序+双指针替代两个for循环
- 注意对 i,j,l,r 的去重
代码:
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
Arrays.sort(nums);
List<List<Integer>> list = new ArrayList<>();
for(int i=0; i<nums.length; i++){
if(i > 0 && nums[i] == nums[i-1]) continue;
for(int j=i+1; j<nums.length; j++){
if(j > i + 1 && nums[j] == nums[j-1]) continue;
int l = j + 1, r = nums.length - 1;
while(l < r) {
long sum = (long)nums[i] + nums[j] + nums[l] + nums[r];
if(sum < target) l++;
else if(sum > target) r--;
else {
list.add(Arrays.asList(nums[i], nums[j], nums[l], nums[r]));
while(l < r && nums[l] == nums[l+1]) l++;
while(l < r && nums[r] == nums[r-1]) r--;
l++; r--;
}
}
}
}
return list;
}
}