代码随想录第十二期集训营-第七天

今天的任务如下:

完成哈希法的剩下题目

454.四数相加II

力扣里有两道四数相加的题,这题比另一题简单,这题是四个独立的数组,而且不用考虑结果集重复的情况。这题思路就是先把A、B数组对应元素相加,存放在Map中,Key为相加和,Value为这个和出现的频率。然后再求出C、D元素对象相加和,然后比较0-sum是否在,如果在就记录Map中对应的Value,最后把Value累加就得到结果,这题比较简单。

383.赎金信

这个和之前的有效字母异位词有点像,只不过异位词这题是两个字符串互相比较,必须完全相同才行。而本题是一个字符串里的字母可以组成另一个字符串就行。这题依然用数组来作为Set,也可以用Map,但是因为小写字母是连续的,用数组好一些。我的思路就是我先遍历赎金信,遇到的字母在数组中元素对应加一,这样就确定每个字母的数量。然后再遍历报纸,判断这个字母是否在赎金信数组中,在的话先判断元素是否大于0,大于的话就减一。最后就看这个数组是否全为0,全为零就对了。我说一下为什么要判断元素是否大于零,假如赎金信里的a有两个,报纸里的a有三个,那我从报纸里找到两个之后就能够满足赎金信里a的数量要求了,所以再找到报纸中的a就不用管了,不需要了。

14.三数之和

这题的难度就提升了不少,因为是在一个数组中,结果集不能重复,所以要去重,但是哈希法去重很麻烦,在代码随想录中有具体讲解,本题采用双指针法。其实一共有三个指针,一个是for循环遍历数组的索引i,一个是指向i后一个元素的指针left,还有一个是指向末尾的right。先对数组进行排序,等下就知道为什么要排序了。每次都求出三个指针对应元素的和,sum = nums[i]+nums[left]+nums[right]。然后判断如果sum>0,说明大了,就要把right左移,变小一点,这就是为什么要排序了。如果sum < 0,说明小了,要把left右移。如果相等,说明找到了。直到sum = 0或者left > right。

如果此时nums[i] > 0,这是就不用再遍历了,肯定找不到了。

然后说一下去重问题,去谁的重,就是这三个指针的重。先去重nums[i],有个细节,是判断nums[i] == nums[i+1]还是判断nums[i] == nums[i-1]呢?

if (nums[i] == nums[i + 1]) { // 去重操作
    continue;
}

如果写成这样会怎么样?假如有一个数组是{-1,-1,2},按照这么判断,前两个相等了就不要第一个-1了,那这样是不是就把一个结果集给干没了,我们的去重是去除重复的结果集而不是不让一个结果集里有重复的元素。所以还得是判断nums[i] == nums[i-1],相当于我们走过的路就不要再走了。应该这么写:

if (i > 0 && nums[i] == nums[i - 1]) {
    continue;
}

接着就是去left、right的重,这两个去重逻辑是一样的,只需要在sum == 0的情况下才会去重。因为sum不等于0时,假如大于0,要把right--,再假如左边的right和他一样,那又如何,sum还是>0,继续左移,left也同理,所以sum != 0时不用考虑去重。只需要在sum == 0是加去重代码就行。

while (left < right && nums[right] == nums[right - 1]) right--;
class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> res = new ArrayList<>();
        //创建三个指针
        
        //双指针法,先要对nums排序
        Arrays.sort(nums);
        for(int i = 0;i < nums.length;i++){
            if(nums[i] > 0){
                return res;
            }
            int left = i+1;
            int right = nums.length - 1;
            //先对i去重,当前i要和前一个i比较,不跟后一个比较
            if(i > 0 && nums[i] == nums[i-1]){
                continue;
            }
            while(right > left){
                int sum = nums[left] + nums[right] + nums[i];
                if(sum > 0){
                    //和大了,right左移,不用考虑重复,即使重复也肯定还是sum大了,继续左移就好
                    right--;
                }else if(sum < 0){
                    left++;
                }else{
                    //相等,就可以把这组数放入list集合中
                    res.add(Arrays.asList(nums[i],nums[left],nums[right]));
                    //要对left和right去重
                    while(left < right && nums[right] == nums[right-1]){
                        right--;
                    }
                    while(left < right && nums[left] == nums[left+1]){
                        left++;
                    }
                    right--;
                    left++;
                }
            }
            
        }

        return res;
    }
}

18.四数之和

这题和上一题思路一样,就是求四个数的和,比三数之和多一层for循环,一共相当于四个指针,其他的去重都一样。有一个细节要注意,就是三数之和当nums[i] > 0就return,这里是行不通的,因为这里我们给定的是target,不是确定值,有可能target < 0。要这么判断:nums[i] > target && (nums[i] >=0 || target >= 0)

#2022毕业即失业取暖地##2022毕业生求职现身说法##2022毕业的你对23届的寄语##如何判断面试是否凉了#
全部评论

相关推荐

Sigma429:极兔啊,薪资开的巨低,还在上海,索性不做笔试了
点赞 评论 收藏
分享
美团开奖了,谁说测开比后端薪资低?谁说前端比后端薪资低?好了你又要说后端可以争取sp、ssp,但是能拿到美团白菜offer的就已经算是人中龙凤了,拿到sp、ssp更是凤毛麟角!依旧劝退后端!你后端学历内卷炼狱!实习经历卷的爆!甚至无法入行!入行了也只是和测开、前端的一般!1.学历,最痛的一击!后端工程师的第一步,走得不是技术,而是学历!想要进入大厂?好好看清楚自己的身份证:没有名校背景,别想着进美团、字节、腾讯!&nbsp;面试官看你的第一眼就会想:“呵,去,给你点面试机会,看看你的技术!”什么?你说自己有技术?不好意思,来点GitHub链接,Project经历,能让面试官笑着赶你走。你没个985、211,双一流,根本就无法站稳在这场技术竞赛的起点。你想进大厂,没学历,没技术!永远只有一个词——&nbsp;“被无情拒绝”。2.&nbsp;薪资:你不过是和前端、测开的一匹马“后端工程师薪资高?能进SSP就是牛逼!”SSP?&nbsp;听起来像是你梦想的银河,但实际上能拿到这个级别的人&nbsp;凤毛麟角,除非你在面试官面前像神话人物一样打了个响指,否则你连SSP的尾巴都摸不着。至于你说的“前端薪资不高”?别逗了,前端都在笑你呢,&nbsp;他们搞个页面,工资比你写个亿级请求接口还多。你说你辛辛苦苦优化API、调度缓存,别人搞个UI设计就能多拿几千块。前端已经不止是个展示层了,他们赚得比你还轻松,而你不过是服务器上疯狂跑“CRUD操作”的那只笨重的工蚁。3.&nbsp;后端的真正意义:修&nbsp;Bug,解决问题,下一份工作还是修&nbsp;Bug有多少人觉得后端是系统架构、数据库优化的高端战场?醒醒吧!&nbsp;后端的真正使命:维护旧项目,修复别人留下的烂摊子。你觉得自己能构建一个完美的系统?不!你只会一边修复技术债务,一边打着&nbsp;“重构”&nbsp;的旗号,换来的是&nbsp;“重构再重构”&nbsp;的无尽循环。而且,别告诉我你能专心写代码。你又要写代码,又要看服务器日志,没事还得帮别人&nbsp;修崩的数据库,给前端数据源做“格式化”。你就是那块永远处于消耗型工作的&nbsp;“万金油”。4.&nbsp;晋升?哈哈哈,你是在做梦!你以为后端开发是一条顺风顺水的快速晋升路线?错!&nbsp;你永远只能在一个“程序员”的岗位上打转,或者你为自己设立目标:“我要成为架构师”,那真的是在妄想。架构师?高级开发?靠近那条道路,你的心脏会先被晋升难度给捏住,你前方只有一座座高不可攀的技术山。别看那些SSP,架构师,架构啥呀?公司里的架构都是前端架构师,你就坐在后端的角落里,照顾着你那些满是错误的API和服务器。5.&nbsp;加班?还是加班!你以为后端开发能像文艺片那样“偶尔加个班”?哈哈,傻了吧!&nbsp;后端开发的生活是无休止的加班和修bug,你不仅要写接口,还得守夜调度、监控系统性能。就连你写的那个“完美的数据库查询”,也可能在&nbsp;第二天&nbsp;被前端因为“页面卡顿”给打回原形。“没有加班,你还能吃什么饭?”你说你是程序员,结果你的生活全是&nbsp;熬夜加班、调试、重启。前端跑个页面,喝个咖啡就能过关,而你呢,熬夜跟数据库调试,最后还是那个穷忙的死循环。6.&nbsp;技术天花板:架构?技术深度?笑死了!后端开发的天花板?那不过是个永远也摸不着的架构师“梦想”,你能掌握几款框架、几种数据库、两三套微服务架构,最后也不过是个&nbsp;管理端的“搬运工”。你没办法“打破天花板”,更没有机会跳出“自己写个爬虫”或者“API接口”的死循环。技术深度?你也不过是&nbsp;“技术债务”的修复者,一天到晚都在修补“老旧系统”的缺陷,偶尔听前端同学聊聊他们React、Vue的最新版本,你根本无法理解他们说的是什么。
开心小狗🐶:感觉后端有点像考研的0812,报名的时候都想冲0812,看不上0854。但是真入学了,不都是众生平等
点赞 评论 收藏
分享
评论
29
3
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务