代码随想录算法训练营第七天 | 454. 四数相加 II、383. 赎金信、15. 三数之和、18. 四数之和

51 阅读1分钟

454. 四数相加 II

把前两个数组之和和次数存储到map,然后后两个数组之和去map找能加起来为0的数,统计总次数就可以了

function fourSumCount(nums1: number[], nums2: number[], nums3: number[], nums4: number[]): number {
  const m: Map<number, number> = new Map()
  for (let i = 0; i < nums1.length; i++) {
    for (let j = 0; j < nums2.length; j++) {
      const sum = nums1[i] + nums2[j]
      m.set(sum, (m.get(sum) || 0) + 1)
    }
  }
  let cnt = 0
  for (let k = 0; k < nums3.length; k++) {
    for (let l = 0; l < nums4.length; l++) {
      const sum = nums3[k] + nums4[l]
      if (m.has(-sum)) {
        cnt += m.get(-sum)
      }
    }
  }
  return cnt
};  

383. 赎金信

把ransomNote中的每个字符和次数存入map,然后用magazine中的字符消减次数,如果某个字符消减后小于0,说明magazine中这个字符不够,即不满足条件

function canConstruct(ransomNote: string, magazine: string): boolean {
  const m: Map<string, number> = new Map()
  for (const c of magazine) {
    m.set(c, (m.get(c) || 0) + 1)
  }
  for (const c of ransomNote) {
    const cnt = (m.get(c) || 0) - 1
    if (cnt < 0) {
      return false
    }
    m.set(c, cnt)
  }
  return true
};

15. 三数之和

双指针法,从0开始循环nums,设左指针为i+1,右指针为末尾,如果三数之和大于0,则右指针左移,如果小于0,则左指针右移,如果等于0,记录结果,左右指针同时移动,注意前提条件是先把nums按升序排序

function threeSum(nums: number[]): number[][] {
  const s: Set<string> = new Set()
  const res: number[][] = []
  nums.sort((a, b) => a - b)
  for (let i = 0; i < nums.length; i++) {
    let l = i + 1
    let r = nums.length - 1
    while (l < r) {
      const sum = nums[i] + nums[l] + nums[r]
      if (sum === 0) {
        const tmp = [nums[i], nums[l], nums[r]]
        tmp.sort((a, b) => a - b)
        if (!s.has(tmp.join(','))) {
          res.push(tmp)
          s.add(tmp.join(','))
        }
        l++
        r--
      } else if (sum > 0) {
        r--
      } else {
        l++
      }
    }
  }
  return res
};

18. 四数之和

思路和三数之和类似,使用双指针法,外面使用两层循环

function fourSum(nums: number[], target: number): number[][] {
  const s: Set<string> = new Set()
  const res: number[][] = []
  nums.sort((a, b) => a - b)
  for (let i = 0; i < nums.length - 1; i++) {
    for (let j = i + 1; j < nums.length; j++) {
      let l = j + 1
      let r = nums.length - 1
      while (l < r) {
        const sum = nums[i] + nums[j] + nums[l] + nums[r]
        if (sum === target) {
          const tmp = [nums[i], nums[j], nums[l], nums[r]]
          tmp.sort((a, b) => a - b)
          if (!s.has(tmp.join(','))) {
            res.push(tmp)
            s.add(tmp.join(','))
          }
          l++
          r--
        } else if (sum < target) {
          l++
        } else {
          r--
        }
      }
    }
  }
  return res
};