454.四数相加II
暴力超时
class Solution {
public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
//超出时间限制
//分别从4个数组中任选一个,四数相加==0
int n = nums4.length,index=0;
int count=0;
int[] arr1=new int[n*n];
int[] arr2=new int[n*n];
int m=arr1.length;
//两辆数组先做加法,找出所有可能
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
arr1[index]=nums1[i]+nums2[j];
arr2[index]=nums3[i]+nums4[j];
index++;
}
}
for(int i=0;i<m;i++){
for(int j=0;j<m;j++){
if(arr1[i]+arr2[j]==0){
count++;
}
}
}
return count;
}
}
卡在这个用例[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
优化,看了下题解用HasMap,思路是差不多的,都是先求两个数组的所有可能元素之和放到map中,然后在map中寻找另外两个数组的所有可能元素之和的相反数
class Solution {
public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
//分别从4个数组中任选一个,四数相加==0
int n=nums1.length;
int count=0;
Map<Integer,Integer> map=new HashMap<Integer,Integer>();
//数组先做加法,找出所有可能的和
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
map.put(nums1[i]+nums2[j],map.getOrDefault(nums1[i]+nums2[j],0)+1);
}
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
count+=map.getOrDefault(-nums3[i]-nums4[j],0);//注意这里直接调用get()方法如果找不到会返回null,所有这里用getOrDfault()方法
}
}
return count;
}
}
383. 赎金信
这道题和242. 有效的字母异位词的思路一样,写的很顺
class Solution {
public boolean canConstruct(String r, String m) {
//判断 ransomNote 能不能由 magazine 里面的字符构成。magazine 中的每个字符只能在 ransomNote 中使用一次。
int[] letter=new int[26];
for(int i=0;i<r.length();i++){
letter[r.charAt(i)-'a']++;
}
for(int i=0;i<m.length();i++){
letter[m.charAt(i)-'a']--;
}
for(int i=0;i<letter.length;i++){
if(letter[i]>0){//说明r有字符没有使用到m中的字符
return false;
}
}
return true;
}
}
15.三数之和(需要二刷)
15. 三数之和
很细节的题目,没有思路
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
//哈希?双指针其实可以理解成是三指针
int len=nums.length;
List<List<Integer>> res=new ArrayList<>();
if(nums == null || len <3){
return res;
}
//排序
Arrays.sort(nums);
//遍历数组中的每一个元素
for(int i=0;i<len;i++){
//如果遍历的起始元素大于0,那么就直接退出
//原因,此时数组为有序的数组,最小的数都大于0了,三树枝和肯定大于0
if(nums[i]>0){
break;
}
//去重,当起始值等于前一个元素时,得到的结果会和前一次相同
if(i>0&&nums[i]==nums[i-1]){continue;}//这里先i>0避免i=0时这里报错
int l=i+1;
int r=len-1;
//当l不等于r时就继续遍历
while(l<r){
//三数相加
int sum=nums[i]+nums[l]+nums[r];
//如果等于0,将结果对应的索引位置的值加入结果集中
if(sum==0){
res.add(Arrays.asList(nums[i],nums[l],nums[r]));
//在将左指针和右指针移动时,先对做左右指针的值进行判断,如果重复可以跳过
//当i不变,如果l取的值和前一个数相同,那么不用计算,直接跳
while(l<r&&nums[l]==nums[l+1]){l++;}
while(l<r&&nums[r]==nums[r-1]){r--;}
l++;r--;
}
else if(sum<0){
l++;
}
else {//sum>0
r--;
}
}
}
return res;
}
}
两行while代码解决下面示例的情况
18.四数之和(需要二刷)
思路和15.三数之和一样,
只不过四数是要两层for循环,先确定一个sum=nums[i]+nums[k]
再判断sum2=sum+nums[l]+nums[r]是否等于target,
target值是否合法判断:将数组nums升序后,比较target和nums[0]
去重判断:
1.if(i > 0 && nums[i - 1] == nums[i]) { continue;}
2.if(k>i+1&&nums[k]==nums[k-1]){continue;}//去重
3.while(l<r&&nums[l]==nums[l+1]){l++;}
4.while(l<r&&nums[r]==nums[r-1]){r--;}
代码:
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
//四树之和II给的是4个数组,且索引下标允许相同
//双指针,和15.三数之和类似
int len=nums.length;
List<List<Integer>> res=new ArrayList<>();
if(nums == null || len <4){
return res;
}
//排序
Arrays.sort(nums);
for(int i=0;i<len;i++){
if (nums[i] > 0 && nums[i] > target) { //如果遍历的起始元素大于target,那么就直接退出 //原因,此时数组为有序的数组,最小的数都大于target了,四数之和肯定大于target
return res;
}
if (i > 0 && nums[i - 1] == nums[i]) { // 对nums[i]去重
continue;
}
for(int k=i+1;k<len;k++){
int sum=nums[i]+nums[k];
//去重,当起始值等于前一个元素时,得到的结果会和前一次相同,在三数之和的target是0
if(k>i+1&&nums[k]==nums[k-1]){continue;}//去重
int l=k+1;
int r=len-1;
//当l不等于r时就继续遍历
while(l<r){
//三数相加
int sum2=sum+nums[l]+nums[r];
//如果等于0,将结果对应的索引位置的值加入结果集中
if(sum2==target){
res.add(Arrays.asList(nums[i],nums[k],nums[l],nums[r]));
//在将左指针和右指针移动时,先对做左右指针的值进行判断,如果重复可以跳过
//当i不变,如果l取的值和前一个数相同,那么不用计算,直接跳
while(l<r&&nums[l]==nums[l+1]){l++;}
while(l<r&&nums[r]==nums[r-1]){r--;}
l++;
r--;
}
else if(sum2<target){
l++;
}
else {//sum>0
r--;
}
}
}
}
return res;
}
}