LeetCode刷题日记之链表II

1.四数相加II

题目描述

在这里插入图片描述

解题思路

1.定义一个哈希Map,其中key存放两数之和,value存放两数和出现的次数。
2.遍历统计出nums1和nums元数相加和出现的次数(a+b)。
3.遍历nums3和nums4,并求和(c+d),统计出(0-(c+d))在Map中出现的次数。
4.返回(0-(c+d))出现次数的累加和。

var fourSumCount = function(nums1, nums2, nums3, nums4) {
   let map = new Map()
   let result = 0;
   for(let i = 0;i<nums1.length;i++) {
       for(let j = 0;j<nums2.length;j++) { // 统计前两个数组元素之和
           let tmp = nums1[i] + nums2[j]
           if(map.has(tmp)){
               map.set(tmp,map.get(tmp) + 1)
           } else {
               map.set(tmp,1)
           }
       }
   }

   for(let i=0;i<nums3.length;i++) {
       for(let j = 0;j<nums4.length;j++) {
           let tmp = nums3[i] + nums4[j]
           if(map.has(0-tmp)){ // 如果map中存在 说明四数相加等于0
               result += map.get(0-tmp)
           }
       }
   }

   return result
};

2.赎金信

题目描述

在这里插入图片描述

解题思路

1.定义一个哈希Map,其中key存放ransomNote中的每个字母,value表示每个字母出现的次数。
2.遍历ransomNote字符串,统计每个字母出现的次数。
3.遍历magazine字符串,Map中的每个字母减去对应的次数。
4.遍历map,判断是否有字母出现次数大于0,有则返回false,否则返回true.

var canConstruct = function(ransomNote, magazine) {
    let map = new Map();
    for(let i = 0;i<ransomNote.length;i++) {
         map.set(ransomNote[i],(map.get(ransomNote[i])|| 0)+1)
    }

    for(let i = 0;i<magazine.length;i++) {
        if(map.has(magazine[i])) {
            map.set(magazine[i],map.get(magazine[i]) - 1)
        }
    }

    for(let [k,v] of map) {
        if(v > 0) {
            return false
        }
    }
    return true
};

3.三数之和

题目描述

在这里插入图片描述

解题思路

1.将数组按照从小到大的顺序排序。
2.遍历数组,在循环中使用双指针,其中左指针表示循环索引+1,右指针为数组末位索引。
3.判断nums[i]+nums[left]+nums[right]=sum和与0的大小。
4.如果sum>0,则右指针左移,如果sum<0,左指针右移,如果sum==0,将对应数据添加入结果中。
5.下次循环继续如此操作,循环中注意去重剪枝。

var threeSum = function(nums) {
   let result = [];
   nums = nums.sort((a,b) => a-b)
   for(let i = 0;i<nums.length;i++) {
    if(nums[i] > 0) {
        return result
    }
    if(i>0&&nums[i] == nums[i-1]) {
        continue
    }
    let left = i + 1;
    let right = nums.length -1
    while(left<right) { // i j k 不相等 所以这儿不能又等于
       let tmp = nums[i] + nums[left] + nums[right]
       if(tmp > 0) {
           right --
       } else if(tmp<0) {
           left ++
       } else {
           result.push([nums[i],nums[left],nums[right]])

           while(left<right && nums[right] == nums[right - 1]) right--
           while(left<right && nums[left] == nums[left+1]) left++ // 去重


           left ++
           right -- // 区间缩小
       }
    }
   }

   return result
};

4.四数之和

题目描述

在这里插入图片描述

解题思路

本题解题思路和三数之和相同,只需将外部循环改为双重循环即可。

var fourSum = function(nums, target) {
     nums = nums.sort((a,b) => a- b);
    const result = [];
    for(let i = 0;i<nums.length;i++) {
        if(nums[i]>target&&target>0){
            break; // 剪枝
        }
        if(i>0&&nums[i] === nums[i-1]){
            continue; // 去重
        }
        for(let j = i+1;j<nums.length-1;j++){
            if(nums[i] + nums[j] > target&&target>0){
                break; // 剪枝
            }
            if(j>i+1&&nums[j] == nums[j-1]){
                continue // 去重
            }
            const twoSum = nums[i] + nums[j]
            let left = j+1;
            let right = nums.length-1
            while(left<right){
                if(twoSum + nums[left]+nums[right] === target) {
                    result.push([nums[i],nums[j],nums[left],nums[right]])
                    while(right>left&&nums[right] == nums[right-1]) {
                        right--
                    }
                    while(right>left&&nums[left] == nums[left+1]){
                        left++
                    }
                    left++
                    right--;
                } else if(twoSum + nums[left] + nums[right] > target) {
                   right --
                  
                } else  {
                    left++;
                }
            } 
        }
    }

    return result
};

猜你喜欢

转载自blog.csdn.net/Salange1/article/details/128309298
今日推荐