day_7 Leetcode 454, 383, 15, 18

Leetcode 454:

https://leetcode.com/problems/remove-linked-list-elements/description/

题目的第一想法:

这道题我的第一想法是看一看能否找到一个O(N)的方法,就是找到一个只需要把四个数组遍历一遍的方法来解决这个问题。但是我找不到一个可行的方式,尤其是和hashmap的组合。

看完代码随想录之后的想法:

看完之后我觉得还是很巧妙的,可以把时间的复杂度的直接开方。具体的逻辑是把四个数组分为两组,然后把第一个数组的数字两两相加后存入hashmap中去。快速写法:

map.put(i+j,map.getOrDefault(i+j,0)+1)

个人写法:

class Solution {
    public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
        HashMap<Integer, Integer> map = new HashMap<>();
        int n = nums1.length;
        int count = 0;
        for(int i = 0; i < n; i++){
            for(int j = 0; j < n; j++){
                int temp = nums1[i] + nums2[j];
                if(map.containsKey(temp)){
                    map.put(temp, map.get(temp) + 1);
                }else{
                    map.put(temp, 1);
                }
            }
        }
        for(int i = 0; i < n; i++){
            for(int j = 0; j < n; j++){
                int temp = nums3[i] + nums4[j];
                if(map.containsKey(0 - temp)){
                    count += map.get(0 - temp);
                }
            }
        }
        return count;
    }
}

Leetcode 383:

https://leetcode.com/problems/remove-linked-list-elements/description/

题目的第一想法:

这道题和之前写过的异位词的问题非常相近。核心逻辑都是使用数组作为hashmap储存出现过的char。然后再遍历一边magazine后检查有没有char没有被留下来。写法如下

class Solution {
    public boolean canConstruct(String ransomNote, String magazine) {
        int alpha[] = new int[26];
        for(int i = 0; i < ransomNote.length(); i++){
            alpha[ransomNote.charAt(i) - 'a']++; 
        }
        for(int i = 0; i < magazine.length(); i++){
            alpha[magazine.charAt(i) - 'a']--; 
        }
        for(int i = 0; i < alpha.length; i++){
            if(alpha[i] > 0){
                return false;
            } 
        }
        return true;
    }
}

Leetcode 15:

https://leetcode.com/problems/3sum/submissions/879845403/

题目的第一想法:

这道题我在做两数和的时候有看到过sort后用双指针的解法。所以大概逻辑是明白的。但在去重上费了很大的力气。本来以为问题是在去重中间数和末尾数上,但结果发现问题出在去重第一个数的过程中。写法如下

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> rlist = new LinkedList<>();
        Arrays.sort(nums);
        for(int i = 0; i < nums.length - 2; i++){
             if(i > 0 && nums[i] == nums[i - 1]){
                continue;
            }
            int l = i + 1;
            int r = nums.length - 1;
            while(l < r){
                List<Integer> list = new LinkedList<>();
                int temp = nums[l] + nums[r];
                if(temp + nums[i] == 0){
                    list.add(nums[i]);
                    list.add(nums[l]);
                    list.add(nums[r]);
                    rlist.add(list);
                    while(l < r && nums[l] == nums[l + 1]){
                        l++;
                    }
                    while(l < r && nums[r] == nums[r - 1]){
                        r--;
                    }
                    l++;
                    r--;
                }else if(temp + nums[i] > 0){
                    r--;
                }else{
                    l++;
                }
            }
        }
        return rlist;
    }
}

Leetcode 18:

https://leetcode.com/problems/4sum/

题目的第一想法:

这道题和3sum的逻辑大同小异,逻辑依旧是sort,双指针外加上去重的问题。多了一层loop也就多了一层去重算法。但令我没想到的是会有超过integer最大值的问题。需要用long来解决,然后在计算等式的右边也需要cast一个long来解决运算过程中的overflow。

/*
-2 -1 0 0 2 1
 a  b l     r
*/
class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        List<List<Integer>> rlist = new ArrayList<>();
        Arrays.sort(nums);
        for(int i = 0; i <= nums.length - 4; i++){
            if((nums[i] > 0 && nums[i] > target) || (i != 0 && nums[i - 1] == nums[i])){
                continue;
            }
            for(int j = i + 1; j <= nums.length - 3; j++){
                if((nums[i] + nums[j] > 0 && nums[i] + nums[j] > target) || (j != i + 1 && nums[j - 1] == nums[j])){
                    continue;
                }
                int l = j + 1;
                int r = nums.length - 1;
                while(l < r){
                    long sum = (long)nums[i] + nums[j] + nums[l] + nums[r];
                    if(sum == Integer.MAX_VALUE || sum == Integer.MIN_VALUE){
                        break;
                    }
                    if(sum == target){
                    rlist.add(Arrays.asList(nums[i], nums[j], nums[l], nums[r]));
                    while(l < r && nums[l] == nums[l + 1]){
                        l++;
                        }
                    while(l < r && nums[r] == nums[r - 1]){
                        r--;
                        }
                    l++;
                    r--;
                     }else if(nums[l] + nums[r] > target - (nums[i] + nums[j])){
                         r--;
                    }else{
                    l++;
                }
                }
            }
        }
        return rlist;
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值