一、四数相加
解题思路
本题要求的是A[i] + B[j] + C[k] + D[l] = 0所以可以转换一下思路,即A[i] + B[j] = 0 -(C[k] + D[l] )。
使用map处理。
(1)用map记录A、B 组的和sum,sum为map的key,sum在A、B 组的和中一共出现的次数为value。
(2)用res记录满足条件的元组个数。
(3)遍历C、D组,若map中能够找到0 -(C[k] + D[l] ),则res+=res+=map.getOrDefault(0-K-I,0).
代码如下:
class Solution {
public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
int res=0;
Map<Integer,Integer> map=new HashMap<Integer,Integer>();
for(int i:nums1){
for(int j:nums2){
int sum=i+j;
map.put(sum,map.getOrDefault(sum,0)+1);
}
}
for(int i:nums3){
for(int j:nums4){
res+=map.getOrDefault(0-i-j,0);
}
}
return res;
}
}
二、赎金信
解题思路
与字母异位数类似,区别是本题第二个字符串的每个字符只能在第一个字符串中使用一次。
这会有两种情况出现:
(1)两个字符串长度相同,也就是第二个字符串中没有重复的字符。
(2)第一个字符串长度小于第二个字符串。
所以解题步骤如下:
(1)遍历第二个字符串并记录每个字母出现的次数。
(2)遍历第一个字符串并在碰到字母(在第二个字符串中出现过)后减1。
(3)遍历 记录字母出现次数的数组res,如果有不为0 的元素,说明不正确。
具体代码如下:
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
if(ransomNote.length()>magazine.length()){
return false;
}
int[] record=new int[26];
for(char c:magazine.toCharArray()){
record[c-'a']+=1;
}
for(char c:ransomNote.toCharArray()){
record[c-'a']-=1;
}
for(int i:record){
if(i<0)
return false;
}
return true;
}
}
三、三数之和
解题思路
采用双指针法。先将数组排序,然后开始进行遍历相加。
具体代码如下:
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> res=new ArrayList<>();
Arrays.sort(nums);
for(int i=0;i<nums.length;i++){
if(nums[i]>0){
return res;
}
if(i>0 && nums[i]==nums[i-1]){
continue;
}
int 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 {
res.add(Arrays.asList(nums[i],nums[left],nums[right]));
while(left<right && nums[right]==nums[right-1]){
right--;
}
while(left<right && nums[left]==nums[left+1]){
left++;
}
right--;
left++;
}
}
}
return res;
}
}
四、四数之和
解题思路
与三数之和做法类似,不过和从0 变为 target。
在三数之和的基础上再加一层循环判断。
具体代码如下:
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
Arrays.sort(nums);
List<List<Integer>> res=new ArrayList<>();
for(int k=0;k<nums.length;k++){
if(nums[k]>target && nums[k]>=0){
break;
}
if(k>0 && nums[k]==nums[k-1]){
continue;
}
for(int i=k+1;i<nums.length;i++){
if(nums[k]+nums[i]>target && nums[k]+nums[i]>=0){
break;
}
if(i>k+1 && nums[i]==nums[i-1]){
continue;
}
int left=i+1;
int right=nums.length-1;
while(right>left){
long sum=(long)nums[k]+nums[i]+nums[left]+nums[right];
if(sum>target){
right--;
}
else if(sum<target){
left++;
}
else {
res.add(Arrays.asList(nums[k],nums[i],nums[left],nums[right]));
while(right>left && nums[right]==nums[right-1])
{
right--;
}
while(right>left && nums[left]==nums[left+1])
{
left++;
}
right--;
left++;
}
}
}
}
return res;
}
public static void main(String[] args) {
Solution solution = new Solution();
int[] nums = {1, 0, -1, 0, -2, 2};
int target = 0;
List<List<Integer>> results = solution.fourSum(nums, target);
for (List<Integer> result : results) {
System.out.println(result);
}
}
}
五、今日收获
前两道题比较好理解,后两道题还是有难度的。后两道题的细节很多,判断条件需要好好考虑,目前我还不能够做到完全不看题解完成后两道题目。
今日学习+解题+博客=2h30min。