代码训练营day07

72 阅读1分钟

四数相加||

题目链接:四数相加

  • 思路:用map存储2数之和,再在map里面查找是否有0 - sum的值
var fourSumCount = function(nums1, nums2, nums3, nums4) {
  const m = new Map()
  let count = 0
  for(const i of nums1) {
    for(const j of nums2) {
      m.set((i + j), (m.get(i + j) || 0) + 1)
    }
  }

  for(const i of nums3) {
    for(const j of nums4) {
      if(m.has(0 - (i + j))) {
        count += m.get(0 - (i + j))
      }
    }
  }

  return count
};

赎金信

题目链接:赎金信

  • 思路:因为有字符串,可以用length为26的数组存储,也可以用map存储
var canConstruct = function(ransomNote, magazine) {
    if(ransomNote.length > magazine.length) return false
    // const m = new Map()
    // for(const i of magazine) {
    //     m.set(i, (m.get(i) || 0) + 1)
    // }
    // for(const j of ransomNote) {
    //     if(!m.get(j)) return false
    //     m.set(j, m.get(j) - 1)
    // }
    // return true
    const base = 'a'.charCodeAt()
    const res = new Array(26).fill(0)
    for(const i of magazine) {
        res[i.charCodeAt() - base]++
    }

    for(const j of ransomNote) {
        if(res[j.charCodeAt() - base]) {
            res[j.charCodeAt() - base]--
            continue
        }
        return false
    }
    return true
};

三数之和

题目链接:三数之和

  • 思路:由于存在重复的三元数组,若用map的话去重比较麻烦,考虑用双指针
var threeSum = function(nums) {
    nums.sort((a, b) => a - b)
    const res = []
    for(let left = 0; left < nums.length - 2; left++) {
        if(nums[left] > 0) return res
        if(left > 0 && nums[left] === nums[left - 1]) continue
        let cur = left + 1, right = nums.length - 1
        while(cur < right) {
            let sum = nums[left] + nums[cur] + nums[right]
            if(sum === 0) {
                res.push([nums[left], nums[cur], nums[right]])
                while(nums[cur] === nums[cur + 1] && cur < right) cur++
                while(nums[right] === nums[right - 1] && cur < right) right--
                cur++
                right--
             } else if(sum > 0) {
                right--
            } else if(sum < 0) {
                cur++
            }
        }
    }
    return res
};

四数之和

题目链接:四数之和

  • 在else里放push逻辑可以减少运行时间,在去重中,需要考虑for里面遍历指针的去重,还有移动指针的去重
var fourSum = function(nums, target) {
    if(nums.length < 4) return []
    nums.sort((a, b) => a - b)
    const res = []
    for(let i = 0; i < nums.length - 3; i++) {
        if(i > 0 && nums[i] === nums[i - 1]) continue
        for(let j = i + 1; j < nums.length - 2; j++) {
            if(j > i + 1 && nums[j] === nums[j - 1]) continue
            let left = j + 1, right = nums.length - 1 
            while(left < right) {
                if(nums[i] + nums[j] + nums[left] + nums[right] > target) {
                    right--
                } else if(nums[i] + nums[j] + nums[left] + nums[right] < target) {
                    left++
                } else {
                    res.push([nums[i], nums[j], nums[left], nums[right]])
                    while(left < right && nums[right] == nums[right - 1]) right--
                    while(left < right && nums[left] == nums[left + 1]) left++
                    right--
                    left++
                }
            }
        }
    }

    return res
};