LeetCode 454.四数相加II
题目链接:力扣
思路:四数之和可以看成两两一组的两数之和,将nums1和nums2数组作为numsA,将nums3和nums4作为numsB,遍历numsA并将元素存入哈希表中,然后查询哈希表中是否存在numsB中的元素即可。
代码:
class Solution {
public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
int res = 0;
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums1.length; i++) {
for (int j = 0; j < nums2.length; j++) {
int key = nums1[i] + nums2[j];
map.put(key, map.getOrDefault(key, 0) + 1);
}
}
for (int i = 0; i < nums3.length; i++) {
for (int j = 0; j < nums4.length; j++) {
int tmpKey = nums3[i] + nums4[j];
if (map.getOrDefault(-tmpKey, 0) != 0) {
res += map.get(-tmpKey);
}
}
}
return res;
}
}
LeetCode 383.赎金信
题目链接:力扣
思路:根据题目的意思,只要magazine中的每个字符在ransomNote中出现且次数一致,则表示可以唯一构成,返回true,否则返回false。直接的方式就是遍历ransomNote中每个字母,将字母出现次数存储在哈希表中,然后遍历magazine中的字母,减去对应字母出现的次数,完成后检查哈希表中各元素的次数,若存在某个元素大于0,则表示ransonNote中的元素并不完全在magazine中。
代码:
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
Map<Character, Integer> map = new HashMap<>();
for (Character ch: magazine.toCharArray()) {
map.put(ch, map.getOrDefault(ch, 0) + 1);
}
for (Character ch: ransomNote.toCharArray()) {
if (map.containsKey(ch)) {
if (map.get(ch) - 1 < 0) {
return false;
} else {
map.put(ch, map.get(ch) - 1);
}
} else {
return false;
}
}
return true;
}
}
LeetCode 15. 三数之和
题目链接:力扣
思路:
(1)按照题目的意思解题,遍历数组元素,判断符合条件的结果。
(2)利用回溯法,暴力搜索所有的解空间,然后剪枝解空间,缩小搜索规模,加速计算。
代码:
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
if (nums.length < 3) { return res; }
Arrays.sort(nums);
for (int i = 0; i < nums.length; i++) {
int tmpSum = -nums[i];
int left = 0, right = nums.length - 1;
List<Integer> tmpRes;
while (left < right && left != i && right != i) {
if (nums[left] + nums[right] < tmpSum) { left++; continue;}
if (nums[left] + nums[right] > tmpSum) { right--; continue;}
if (nums[left] + nums[right] == tmpSum) {
tmpRes = new ArrayList<>();
int[] tmpArr = new int[3];
tmpArr[0] = nums[i]; tmpArr[1] = nums[left]; tmpArr[2] = nums[right];
Arrays.sort(tmpArr);
for (int item: tmpArr) { tmpRes.add(item); }
if (!res.contains(tmpRes)) { res.add(tmpRes); }
left++;
right--;
}
}
}
return res;
}
}
LeetCode 18. 四数之和
题目链接:力扣
思路:这道题按照一般思路没有解出来,后边再补。(有回溯版本可以参考)
代码:
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> res = new ArrayList<>();
LinkedList<Integer> path = new LinkedList<>();
Arrays.sort(nums);
long curSum = 0L;
dfs(path,res,nums,target,0,curSum);
return res;
}
private void dfs(LinkedList<Integer> path, List<List<Integer>> res, int[] nums, int target,int begin,long curSum) {
if (target == -294967296) {
return ;
}
if(path.size()==4){
if(target==curSum){
res.add(new ArrayList<>(path));
return;
}
}
for (int i = begin; i < nums.length; i++) {
if(nums.length-i < 4-path.size()) return;
if(begin!=i&&nums[i-1]==nums[i]) continue;
if(i<nums.length-1&&(curSum+nums[i]+(long)(3-path.size())*nums[i+1])>target) return;
if(i<nums.length-1&&(curSum+nums[i]+(long)(3-path.size())*nums[nums.length-1])<target) continue;
curSum+=nums[i];
path.offerLast(nums[i]);
dfs(path,res,nums,target,i+1,curSum);
path.pollLast();
curSum-=nums[i];
}
}
}