加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

四数之和(力扣网)

(2022-04-13 10:14:49)
标签:

js

分类: Html.css.js
闲来无事,刷个题!

给你一个由 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
    -109 <= nums[i] <= 109
    -109 <= target <= 109

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/4sum

话不多说,先上代码:

var fourSum function(numstarget{
    var len nums.length,result [];
    if(len 4)return result;
    nums.sort(function(a,b){return a-b;})
    for(var i 0;i len 3i++){
        if(i 0 && nums[i== nums[i-1])continue;
        if((nums[inums[i+1nums[i+2nums[i+3])> target)break;
        if((nums[inums[len-3nums[len-2nums[len-1])<</span>target)continue;
        for(var j i+1j len-2j++){
            if(j i+1 && nums[j== nums[j-1])continue;
            if((nums[inums[jnums[j+1nums[j+2])>target)break;
            if((nums[inums[jnums[len-2nums[len-1])<</span>target)continue;
            var left j+1,right len-1;
            while(left right){
                var sum nums[inums[jnums[leftnums[right];
                if(sum == target){
                    result.push([nums[i],nums[j],nums[left],nums[right]]);
                    while(left right && nums[left== nums[left+1])left++;
                    left++;
                    while(left right && nums[right== nums[right-1])right--;
                    right--;
                }else if(sum target){
                    right--;
                }else{
                    left++;
                }
            }
        }
    }
    return result;
};
裂开,编辑半天,点保存让我重新登录,然后…没了四数之和(力扣网),只能再来一次。
我丢,现在写博客还要审核,未审核的还不能继续修改,新浪现在是玩啥?四数之和(力扣网)

此题理清了,并不难,不过看着倒是有点难度,从一个数组里选出四个值之和满足目标值,这要是遍历的话,怎么说也得三层,三层遍历复杂度就有点高了。
所以,我前面大部分时间都沉浸在降维上,(最好按照第一思路写出一个正确的程序,然后优化)
当我看到官方给的结题思路后,我有点想戳自己,不就是我一开始的想法么,三层循环。

现在说说结题思路:
首先,数组排个升序,这里请不要问为什么,等下就知道了。
排序之后,就开始遍历,没错,就是挨个找,看到这,是不是感觉不只是三层循环,这似乎要四层,毕竟是选四个,一层循环筛选一个,不就是四个么。

容我道来三层循环的缘由。
首先前两个数字的筛选用两个for询嵌套遍历,大家应该都没有问题,那么就好好说第三层的遍历。
现在需要的是确认第三与第四个数字,即两数之和等于某个值val,这对于有序数组不是很好处理。
第一,判断数组前两个值是否大于目标值val,大于,肯定不需要继续遍历下去。
第二,判断数组后两个值是否小于目标值val,小于也肯定不需要继续遍历。
上面两种情况一排除,就剩最后一种可以继续遍历的情况。
左边L,右边R,和sum
sum>val ,R--,即 右边往左挪一位;
sum《val,L++,即 左边往右挪一位;
sum==val,R--,L++,即 两边往中间各挪一位;
直到 L>=R,结束循环。
这里有一点要注意,那就是重复数据,如果遇到重复数据,继续挪一位。

上面便是第三层循环的逻辑,现在到第二层循环,也就是说第一个数字已经确定,在遍历第二个数字,是的,遍历第二个数字!
因为第三第四个数字的遍历我们已经打包好了,现在就是只看第二个数字。
同第三层循环,需要排除三种情况:
第一,数组前三个数之和大于目标值,这个可以直接跳出第二层循环;(这里有没有很奇怪的感觉,为何不直接与第三层遍历的第一种情况合并,这个大家可以画个图,这个新浪保存一次,得等十几分的审核才行)
第二,数组 第j个 与 后两个数之和小于目标值,这个也是直接跳过循环,进行下一次循环;
第三,第j个 与第j-1个的数值一样,直接跳过;

这是第三次重新书写了,我裂开了。

第一层循环,与第二层类似,不想多描述了,改一次等十几分,要么突然就登录超时,需要重新登录,难受

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有