代码随想录算法训练营第七天| 454. 四数相加II、383.赎金信、15. 三数之和 18.四数之和(Java)
454 四数相加II
package com.shuzijun.leetcode.editor.en;
import java.util.HashMap;
public class FourSumIi{
public static void main(String[] args) {
Solution solution = new FourSumIi().new Solution();
}
//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
//题目统计次数
//仿照两数之和,构造map,key为a+b,value为 a+b出现的次数
//再遍历c和d数组找符合 0-(a+b)的数据,并加和次数
HashMap<Integer, Integer> map = new HashMap<>();
int temp=0;
int result=0;
//遍历nums1和nums2,存储加值和次数
for (int i = 0; i < nums1.length; i++) {
for (int j = 0; j < nums2.length; j++) {
temp=nums1[i]+nums2[j];
if(map.containsKey(temp)){
map.put(temp, map.get(temp)+1);
}else {
map.put(temp,1);
}
}
}
//遍历后判定hashTable里是否包含满足条件,并加和所有满足等于0的次数
for (int i = 0; i < nums3.length; i++) {
for (int j = 0; j < nums4.length; j++) {
temp=nums3[i]+nums4[j];
if (map.containsKey(0-temp)){
result+=map.get(0-temp);
}
}
}
return result;
}
}
//leetcode submit region end(Prohibit modification and deletion)
}
383赎金信
/**
给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。
如果可以,返回 true ;否则返回 false 。
magazine 中的每个字符只能在 ransomNote 中使用一次。
示例 1:
输入:ransomNote = "a", magazine = "b"
输出:false
示例 2:
输入:ransomNote = "aa", magazine = "ab"
输出:false
示例 3:
输入:ransomNote = "aa", magazine = "aab"
输出:true
提示:
1 <= ransomNote.length, magazine.length <= 10⁵
ransomNote 和 magazine 由小写英文字母组成
Related Topics哈希表 | 字符串 | 计数
👍 639, 👎 0bug 反馈 | 使用指南 | 更多配套插件
*/
package com.shuzijun.leetcode.editor.en;
public class RansomNote{
public static void main(String[] args) {
Solution solution = new RansomNote().new Solution();
}
//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
int[] alpha = new int[26];
for (int i = 0; i < magazine.length(); i++) {
alpha[magazine.charAt(i)-'a']++;
}
boolean flag=true;
//randsomNote中必须出现在magazine中,且每个元素的次数要小于maginze的次数
for (int i = 0; i < ransomNote.length(); i++) {
if(alpha[ransomNote.charAt(i)-'a']>0){
alpha[ransomNote.charAt(i)-'a']--;
}else{
flag=false;
break;
}
}
return flag;
}
}
//leetcode submit region end(Prohibit modification and deletion)
}
15 三数之和
/**
给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,
同时还满足 nums[i] + nums[j] + nums[k] == 0 。请
你返回所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例 1:
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。
注意,输出的顺序和三元组的顺序并不重要。
示例 2:
输入:nums = [0,1,1]
输出:[]
解释:唯一可能的三元组和不为 0 。
示例 3:
输入:nums = [0,0,0]
输出:[[0,0,0]]
解释:唯一可能的三元组和为 0 。
提示:
3 <= nums.length <= 3000
-10⁵ <= nums[i] <= 10⁵
Related Topics数组 | 双指针 | 排序
👍 5659, 👎 0bug 反馈 | 使用指南 | 更多配套插件
*/
package com.shuzijun.leetcode.editor.en;
import java.util.ArrayList;
import java.util.Arrays;
public class ThreeSum{
public static void main(String[] args) {
Solution solution = new ThreeSum().new Solution();
}
//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> arrayList = new ArrayList<>();
if (nums.length<3 || nums==null){
return arrayList;
}
//排序数组
Arrays.sort(nums);
for (int i = 0; i < nums.length; i++) {
//三元组第一个元素如果大于0则不可能凑成满足题意的元组
if(nums[i]>0){
return arrayList;
}
//三元组第一个元素去重
if(i>0&& nums[i]==nums[i-1]){
continue;
}
//构造双指针分别从数组前后侧扫描
int left=i+1;
int right= nums.length-1;
while (right>left){
//
int sum=nums[i]+nums[left]+nums[right];
//如果值大于0,说明right大了,左移right
if(sum>0){
right--;
//left小了
}else if(sum<0){
left++;
}else{
arrayList.add(Arrays.asList(nums[i],nums[left],nums[right]));
//针对找到元组后的第二和第三个元素去重
while(right>left && nums[right]==nums[right-1]) right--;//说明left和i确定的情况下,right有多个,我们只计算一次
while(right>left && nums[left]==nums[left+1]) left++;//
//无重复元素了,需要在位移一次
right--;
left++;
}
}
}
return arrayList;
}
}
//leetcode submit region end(Prohibit modification and deletion)
}
18.四数之和
/**
给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b],
nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):
0 <= a, b, c, d < n
a、b、c 和 d 互不相同
nums[a] + nums[b] + nums[c] + nums[d] == target
你可以按 任意顺序 返回答案 。
示例 1:
输入:nums = [1,0,-1,0,-2,2], target = 0
输出:[[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]
示例 2:
输入:nums = [2,2,2,2,2], target = 8
输出:[[2,2,2,2]]
提示:
1 <= nums.length <= 200
-10⁹ <= nums[i] <= 10⁹
-10⁹ <= target <= 10⁹
Related Topics数组 | 双指针 | 排序
👍 1509, 👎 0bug 反馈 | 使用指南 | 更多配套插件
*/
package com.shuzijun.leetcode.editor.en;
import java.util.ArrayList;
import java.util.Arrays;
public class FourSum{
public static void main(String[] args) {
Solution solution = new FourSum().new Solution();
}
//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> result = new ArrayList<>();
Arrays.sort(nums);
for (int i = 0; i < nums.length; i++) {
//跳过不符合数据--剪枝
if(nums[i]>0 && nums[i]>target){
return result;
}
//四元组首位元素去重,第一个元组遍历确认后,第二个元组不需要再遍历,需要去重
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 left =j+1;
int right = nums.length-1;
while(right>left){
long sum=(long) nums[i]+nums[j]+nums[left]+nums[right];
if(sum>target){
right--;
}else if (sum<target){
left++;
}else{
result.add(Arrays.asList(nums[i],nums[j],nums[left],nums[right]));
//left right去重
while(right>left && nums[right]==nums[right-1]) right--;
while(right>left & nums[left] == nums[left+1]) left++;
right--;
left++;
}
}
}
}
return result;
}
}
//leetcode submit region end(Prohibit modification and deletion)
}