力扣算法题

<!--
 * @Description: 
 * @Version: 1.0
 * @Date: 2021-09-23 13:30:48
-->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>力扣题</title>
</head>

<body>

</body>
<script>
  // 给定一个包含 [0, n] 中 n 个数的数组 nums ,找出 [0, n] 这个范围内没有出现在数组中的那个数。
  var missingNumber = function (nums) {
    let res
    let newNums = nums.sort((a, b) => {
      return a - b
    })
    if (newNums[0] != 0) {
      return 0
    }
    for (let i = 0; i < newNums.length; i++) {
      if (newNums[i] != i) {
        return i
      }
    }
    return (res || res == 0) ? res : nums[nums.length - 1] + 1;
  };
  nums = [0, 1, 2, 3, 4, 5, 6, 7]
  // console.log(missingNumber(nums))

  // 给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
  // 请你将两个数相加,并以相同形式返回一个表示和的链表。
  // 你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

  /**
   * Definition for singly-linked list.
   * function ListNode(val, next) {
   *     this.val = (val===undefined ? 0 : val)
   *     this.next = (next===undefined ? null : next)
   * }
   */
  /**
   * @param {ListNode} l1
   * @param {ListNode} l2
   * @return {ListNode}
   */
  var addTwoNumbers = function (l1, l2) {
    let result = new ListNode(0)
    let nowNode = result
    let carry = 0
    // while (l1 || l2 || carry) {
    //   let sum = (l1 ? .val || 0) + (l2 ? .val || 0) + carry
    //   nowNode = nowNode.next = new ListNode(sum % 10)
    //   carry = parseInt(sum / 10)
    //   if (l1) l1 = l1.next
    //   if (l2) l2 = l2.next
    // }
    return result.next
  };
  l1 = [9, 9], l2 = [9]
  // addTwoNumbers(l1, l2)

  // 给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.' 和 '*' 的正则表达式匹配。
  // '.' 匹配任意单个字符
  // '*' 匹配零个或多个前面的那一个元素
  // 所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。
  var isMatch = function (s, p) {
    let reg = new RegExp(`^${p}$`);
    return reg.test(s);
  };
  s = "aa"
  p = "a*"
  // isMatch(s, p)
  // 罗马数字转整数
  var romanToInt = function (s) {
    var mapArr = {
      'a': 900,
      'b': 400,
      'c': 90,
      'd': 40,
      'e': 9,
      'f': 4,
      'M': 1000,
      'D': 500,
      'C': 100,
      'L': 50,
      'X': 10,
      'V': 5,
      'I': 1,
    }
    let str = s.replace(/CM/g, "a").replace(/CD/g, "b").replace(/XC/g, "c").replace(/XL/g, "d").replace(/IX/g, "e")
      .replace(/IV/g, "f")
    let res = null
    for (let char of str) {
      res += mapArr[char]
    }
    return res
  }
  // romanToInt("MCMXCIV")

  // 整数转罗马数字
  var intToRoman = function (num) {
    let str = ""
    var mapArr = {
      'M': 1000,
      'CM': 900,
      'D': 500,
      'CD': 400,
      'C': 100,
      'XC': 90,
      'L': 50,
      'XL': 40,
      'X': 10,
      'IX': 9,
      'V': 5,
      'IV': 4,
      'I': 1,
    }
    for (const key in mapArr) {
      if (num >= mapArr[key]) {
        let len = parseInt(num / mapArr[key])
        for (let i = 0; i < len; i++) {
          str += key
        }
        num -= mapArr[key] * len
      }
    }
    console.log(str)
    return str
  };
  num = 20
  // intToRoman(num)

  // 给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
  var singleNumber = function (nums) {
    return nums.reduce((a, b) => a ^ b)
  };
  // console.log(singleNumber([2, 2, 1]))

  // 编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 '1' 的个数(也被称为汉明重量)。
  var hammingWeight = function (n) {
    let num = n.toString().split("").filter(item => {
      return item == 1
    })
    return num.length
  };
  var num = '00000000000000000000000000001011'
  // console.log(hammingWeight(num))

  // 实现 pow(x, n) ,即计算 x 的 n 次幂函数(即,xn)。
  var myPow = function (x, n) {
    return Math.pow(x, n)
  };
  x = 2.00000, n = 10
  myPow(x, n)

  // 给你一个整数 n,请你判断该整数是否是 2 的幂次方。如果是,返回 true ;否则,返回 false 。
  // 如果存在一个整数 x 使得 n == 2x ,则认为 n 是 2 的幂次方。
  var isPowerOfTwo = function (n) {
    if (n <= 0) return false
    // & 按位与
    return (n & 1) == 0;
  };
  //  console.log(isPowerOfTwo(41))

  // 给定一个整数,写一个函数来判断它是否是 3 的幂次方。如果是,返回 true ;否则,返回 false 。
  // 整数 n 是 3 的幂次方需满足:存在整数 x 使得 n == 3x
  var isPowerOfThree = function (n) {
    if (n < 1) return false
    if (n == 1) return true
    while (n > 0) {
      if (n % 3 == 0) {
        if (n / 3 == 1) {
          return true
        }
        n = n / 3
      } else {
        return false
      }
    }
  };
  // console.log(isPowerOfThree(-3))

  // 给定一个整数,写一个函数来判断它是否是 4 的幂次方。如果是,返回 true ;否则,返回 false 。
  // 整数 n 是 4 的幂次方需满足:存在整数 x 使得 n == 4x
  var isPowerOfFour = function (n) {
    if (n < 1) return false
    if (n == 1) return true
    while (n > 0) {
      if (n % 4 == 0) {
        if (n / 4 == 1) {
          return true
        }
        n = n / 4
      } else {
        return false
      }
    }
  };
  // console.log(isPowerOfFour(4))

  // 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
  var moveZeroes = function (nums) {
    let id = 0;
    for (let i = 0; i < nums.length; i++) {
      if (nums[i]) {
        [nums[id], nums[i]] = [nums[i], nums[id]];
        id++;
      }
    }
    return nums;
  };
  // console.log(moveZeroes([0, 1, 0, 3, 12]))

  // 找出数组中重复的数字。
  // 在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。

  var findRepeatNumber = function (nums) {
    let num1 = {}
    let res
    nums.forEach(item => {
      if (num1[item]) {
        num1[item] += 1
        if (num1[item] > 1) {
          res = item
        }
      } else {
        num1[item] = 1
      }
    })
    return res
  };
  // console.log(findRepeatNumber([2, 3, 1, 0, 2, 5, 3]))

  // 请实现一个函数,把字符串 s 中的每个空格替换成"%20"。
  var replaceSpace = function (s) {
    // let d = s.replace(/\s/g,"%20")
    return s.replace(/\s/g, "%20")
  };
  s = "We are happy."
  // console.log(replaceSpace(s))


  // 给定两个排序后的数组 A 和 B,其中 A 的末端有足够的缓冲空间容纳 B。 编写一个方法,将 B 合并入 A 并排序。
  // 初始化 A 和 B 的元素数量分别为 m 和 n。
  var merge = function (A, m, B, n) {
    return [...A, ...B].filter(item => item > 0).sort((a, b) => a - b)

  };
  A = [1, 2, 3, 0, 0, 0], m = 3
  B = [2, 5, 6], n = 3
  // console.log(merge(A, m, B, n))

  // 给定一个非负整数 num,反复将各个位上的数字相加,直到结果为一位数。
  var addDigits = function (num) {
    while (num > 9) {
      let sum = 0
      num.toString()
      let str = num.toString()
      for (const key of str) {
        sum += parseInt(key)
      }
      num = sum
    }
    return num
    // while(num>9){
    //   let sum = 0
    //   num.toString().split("").forEach(item => {
    //     sum += parseInt(item)
    //   })
    //   num = sum
    // }
    // return num
  };
  // console.log(addDigits(38))


  // 存在一种仅支持 4 种操作和 1 个变量 X 的编程语言:
  // ++X 和 X++ 使变量 X 的值 加 1
  // --X 和 X-- 使变量 X 的值 减 1
  // 最初,X 的值是 0
  // 给你一个字符串数组 operations ,这是由操作组成的一个列表,返回执行所有操作后, X 的 最终值 。
  var finalValueAfterOperations = function (operations) {
    var arr = {
      "++X": +1,
      "X++": +1,
      "--X": -1,
      "X--": -1,
    }
    let sum = 0
    operations.forEach(item => {
      sum += arr[item]
    })
    return sum
  };
  operations = ["++X", "++X", "X++"]
  // console.log(finalValueAfterOperations(operations))

  // 给你一个数组 nums 。数组「动态和」的计算公式为:runningSum[i] = sum(nums[0]…nums[i]) 。
  // 请返回 nums 的动态和。
  var runningSum = function (nums) {
    nums.forEach((item, index) => {
      return nums[index + 1] += nums[index]
    })
    return nums.splice(0, nums.length - 1)
  };
  nums = [1, 2, 3, 4]
  // console.log(runningSum(nums))

  // 给你两个整数,n 和 start 。
  // 数组 nums 定义为:nums[i] = start + 2*i(下标从 0 开始)且 n == nums.length 。
  // 请返回 nums 中所有元素按位异或(XOR)后得到的结果。
  var xorOperation = function (n, start) {
    let res = 0
    for (let i = 0; i < n; i++) {
      res ^= (start + 2 * i)
    }
    return res
  };
  n = 5, start = 0
  // console.log(xorOperation(n, start))
  // 输入:n = 5, start = 0
  // 输出:8
  // 解释:数组 nums 为 [0, 2, 4, 6, 8],其中 (0 ^ 2 ^ 4 ^ 6 ^ 8) = 8 。
  //      "^" 为按位异或 XOR 运算符。



  // 字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。
  var reverseLeftWords = function (s, n) {
    let res = s.substring(n) + s.substring(0, n)
    return res
    console.log(res)
  };
  s = "abcdefg", k = 2 //"cdefgab"
  // reverseLeftWords(s, k)

  // 如果一个十进制数字不含任何前导零,且每一位上的数字不是 0 就是 1 ,那么该数字就是一个 十-二进制数 。例如,101 和 1100 都是 十-二进制数,而 112 和 3001 不是。
  // 给你一个表示十进制整数的字符串 n ,返回和为 n 的 十-二进制数 的最少数目。

  var minPartitions = function (n) {
    let res
    return Math.max(...n.split(""))
  };
  n = "32"
  minPartitions(n)

  // 统计一个数字在排序数组中出现的次数。
  var search = function (nums, target) {
    let count = 0
    nums.map(item => {
      if (item == target) {
        count++
      }
    })
    console.log(count)
    return count
  };
  nums = [5, 7, 7, 8, 8, 10], target = 8
  // search(nums, target)


  // 给你一个整数数组 nums ,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次 。请你找出并返回那个只出现了一次的元素。
  var singleNumber = function (nums) {
    let object = {}
    nums.map(item => {
      if (object[item]) {
        object[item]++
      } else {
        object[item] = 1
      }
    })
    for (const key in object) {
      if (object[key] == 1) {
        res = key
      }
    }
    // console.log(res)
    return res
  };

  nums = [2, 2, 3, 2]
  singleNumber(nums)

  // 给定一个非负整数 n ,请计算 0 到 n 之间的每个数字的二进制表示中 1 的个数,并输出一个数组。
  var countBits = function (n) {
    let num = []
    for (let i = 0; i <= n; i++) {
      let arr = i.toString(2).split("").filter(item => {
        return item == 1
      })
      num.push(arr.length)
    }
    return num
    console.log(num)
  };
  // countBits(5)

  // 给定一个已按照 升序排列  的整数数组 numbers ,请你从数组中找出两个数满足相加之和等于目标数 target 。
  // 函数应该以长度为 2 的整数数组的形式返回这两个数的下标值。numbers 的下标 从 0 开始计数 ,所以答案数组应当满足 0 <= answer[0] < answer[1] < numbers.length 。
  // 假设数组中存在且只存在一对符合条件的数字,同时一个数字不能使用两次。

  var twoSum = function (nums, target) {
    let map = new Map();
    for (let i = 0; i < nums.length; i++) {
      let value = target - nums[i];
      if (map.has(value)) {
        return [map.get(value), i];
      } else {
        map.set(nums[i], i);
      }
    }
    return res;
  };
  numbers = [1, 2, 4, 6, 10], target = 0
  twoSum(numbers, target)

  // 实现一个算法,确定一个字符串 s 的所有字符是否全都不同。
  var isUnique = function (astr) {
    let arr = astr.split("")
    return new Set([...arr]).size == arr.length

  };
  s = "leetcodee"
  isUnique(s)

  // 给定两个字符串 s1 和 s2,请编写一个程序,确定其中一个字符串的字符重新排列后,能否变成另一个字符串。
  var CheckPermutation = function (s1, s2) {
    return s1.split('').sort().join('') == s2.split('').sort().join('')
  };
  s1 = "abc", s2 = "bca"
  CheckPermutation(s1, s2)

  // URL化。编写一种方法,将字符串中的空格全部替换为%20。假定该字符串尾部有足够的空间存放新增字符,并且知道字符串的“真实”长度。(注:用Java实现的话,请使用字符数组实现,以便直接在数组上操作。)
  var replaceSpaces = function (S, length) {
    return S.substring(0, length).replace(/\s/g, "%20")
  };
  replaceSpaces("               ", 5)

  // 字符串有三种编辑操作:插入一个字符、删除一个字符或者替换一个字符。 给定两个字符串,编写一个函数判定它们是否只需要一次(或者零次)编辑。
  var oneEditAway = function (first, second) {
    if (first == second) return true
    let l1 = first.length
    let l2 = second.length
    let str1 = l1 > l2 ? first.split("") : second.split("")
    let str2 = l1 > l2 ? second.split("") : first.split("")
    if (str1.length - str2.length > 2) return false
    let res = 0
    if (str1.length - str2.length == 0) {
      str1.forEach((item, index) => {
        console.log(str2)
        if (item != str2[index]) {
          str2[index] = item
          res += 1
        }
      })
    } else {
      str1.forEach((item, index) => {
        if (item != str2[index]) {
          res += 1
          str2.splice(index, 0, item)
        }
      })
    }
    return res == 1 ? true : false
  };
  first = "pales"
  second = "ple"
  // console.log(oneEditAway(first, second))


  // 输入数字 n,按顺序打印出从 1 到最大的 n 位十进制数。比如输入 3,则打印出 1、2、3 一直到最大的 3 位数 999。
  var printNumbers = function (n) {
    let res = []
    let count = ""
    for (let j = 0; j < n; j++) {
      count += "9"
    }
    for (let i = 1; i <= count; i++) {
      res.push(i)
    }
    return res
  };
  // console.log(printNumbers(2))

  // 我们定义,在以下情况时,单词的大写用法是正确的:
  //   全部字母都是大写,比如 "USA" 。
  //   单词中所有字母都不是大写,比如 "leetcode" 。
  //   如果单词不只含有一个字母,只有首字母大写, 比如 "Google" 。
  //   给你一个字符串 word 。如果大写用法正确,返回 true ;否则,返回 false 。
  var detectCapitalUse = function (word) {
    var count = 0
    for (let i = 0; i < word.length; i++) {
      var c = word.charAt(i)
      if (/^[A-Z]+$/.test(word[i])) {
        count++
      }
    }
    if (count == word.length || count == 0) {
      return true
    } else if (count == 1) {
      if (/^[A-Z]+$/.test(word[0])) {
        return true
      } else {
        return false
      }
    } else {
      return false
    }
  };
  // console.log(detectCapitalUse("ffffffffffffffffffffF"))


  // 给你一个整数数组 nums 和两个整数 k 和 t 。请你判断是否存在 两个不同下标 i 和 j,使得 abs(nums[i] - nums[j]) <= t ,同时又满足 abs(i - j) <= k 。
  // 如果存在则返回 true,不存在返回 false。
  var containsNearbyAlmostDuplicate = function (nums, k, t) {
    let res = false
    // nums.map((item1, index1) => {
    //   nums.map((item2, index2) => {
    //     if (index1 != index2) {
    //       if (Math.abs(item1 - item2) <= t && Math.abs(index1 - index2) <= k) {
    //         res = true
    //       }
    //     }
    //   })
    // })
    for (let i = 0; i < nums.length; i++) {
      for (let j = 0; j < nums.length; j++) {
        if (i != j) {
          if (Math.abs(nums[i] - nums[j]) <= t && Math.abs(i - j) <= k) {
            res = true
            break
          }
        }

      }

    }
    return res
  };
  nums = [1, 2, 3, 1], k = 3, t = 0
  // console.log(containsNearbyAlmostDuplicate(nums, k, t))


  // 给定一个整数数组 nums 和一个整数 k ,请返回其中出现频率前 k 高的元素。可以按 任意顺序 返回答案。
  var topKFrequent = function (nums, k) {
    let object = {}
    nums.map(item => {
      if (object[item]) {
        object[item]++
      } else {
        object[item] = 1
      }
    })

    var newobj = Object.keys(object).sort((a, b) => {
      return object[b] - object[a]
    })
    return newobj.slice(0, k)
  };
  nums = [4, 1, -1, 2, -1, 2, 3], k = 2
  // console.log(topKFrequent(nums,k))


  // 给定两个以升序排列的整数数组 nums1 和 nums2 , 以及一个整数 k 。
  // 定义一对值 (u,v),其中第一个元素来自 nums1,第二个元素来自 nums2 。
  // 请找到和最小的 k 个数对 (u1,v1),  (u2,v2)  ...  (uk,vk) 。
  var kSmallestPairs = function (nums1, nums2, k) {
    let res = []
    let sum = new Map()
    let count = 0
    nums1.map(item2 => {
      nums2.map(item1 => {
        res.push([item2, item1])
        sum.set(count, item2 + item1)
        count++
      })
    })
    const resultArr = Array.from(sum).sort((a, b) => {
      return a[1] - b[1]
    }).slice(0, k)
    let resArr = []
    resultArr.map(item => {
      resArr.push(res[item[0]])
    })
    return resArr
  };
  nums1 = [1, 2], nums2 = [3], k = 3
  // console.log(kSmallestPairs(nums1, nums2, k))
  // 编写一个函数,不用临时变量,直接交换numbers = [a, b]中a与b的值。
  var swapNumbers = function (numbers) {
    return numbers.reverse()
  };
  numbers = [1, 2]
  // console.log(swapNumbers(numbers))

  // 一个有名的按摩师会收到源源不断的预约请求,每个预约都可以选择接或不接。在每次预约服务之间要有休息时间,因此她不能接受相邻的预约。给定一个预约请求序列,替按摩师找到最优的预约集合(总预约时间最长),返回总的分钟数。
  var massage = function (nums) {
    const len = nums.length;
    if (!len) return 0;
    const dp = [nums[0], Math.max(nums[0], nums[1])];
    for (let i = 2; i < len; i++) {
      dp[i] = Math.max(dp[i - 2] + nums[i], dp[i - 1]);
    }
    return dp[len - 1];
  };
  // console.log(massage([1,2,3,1]))


  // 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
  // 给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。
  var rob = function (nums) {
    var len = nums.length
    if (!len) return 0
    const arr = [nums[0], Math.max(nums[0], nums[1])]
    for (let i = 2; i < len; i++) {
      arr[i] = Math.max(arr[i - 1], arr[i - 2] + nums[i])
    }
    return arr[len - 1]
  };
  // console.log(rob([1, 2, 3, 1]))
  //   请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C++ 中的 atoi 函数)。

  // 函数 myAtoi(string s) 的算法如下:

  // 读入字符串并丢弃无用的前导空格
  // 检查下一个字符(假设还未到字符末尾)为正还是负号,读取该字符(如果有)。 确定最终结果是负数还是正数。 如果两者都不存在,则假定结果为正。
  // 读入下一个字符,直到到达下一个非数字字符或到达输入的结尾。字符串的其余部分将被忽略。
  // 将前面步骤读入的这些数字转换为整数(即,"123" -> 123, "0032" -> 32)。如果没有读入数字,则整数为 0 。必要时更改符号(从步骤 2 开始)。
  // 如果整数数超过 32 位有符号整数范围 [−231,  231 − 1] ,需要截断这个整数,使其保持在这个范围内。具体来说,小于 −231 的整数应该被固定为 −231 ,大于 231 − 1 的整数应该被固定为 231 − 1 。
  // 返回整数作为最终结果。
  var myAtoi = function (s) {
    let str = s.trim()
    let res = ""
    let count = 0
    if (str[0] == "-" || str[0] == "+") {
      if (str.length == 1) return 0
      res += str[0]
      count++
    }

    for (let i = count; i < str.length; i++) {
      var reg = /[0-9]/
      if (!reg.test(str[i])) {
        if (res == "-" || res == "+") {
          return 0
        }
        if (res > 2147483647) {
          res = 2147483647
        } else if (res < -2147483648) {
          res = -2147483648
        }
        return res == "" ? 0 : res
      } else {
        res += str[i]
      }
    }

    if (res > 2147483647) {
      res = 2147483647
    } else if (res < -2147483648) {
      res = -2147483648
    }
    return res
  };
  s = "      -11919730356x"
  // console.log(myAtoi(s))

  // 给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
  // 注意:答案中不可以包含重复的三元组。
  var threeSum = function (nums) {
    if (nums.length < 3) return []
    let res = []
    if (nums.join("") == 0) {
      res.push([0, 0, 0])
      return res
    }
    nums.sort((a, b) => a - b)
    for (let i = 0; i < nums.length; i++) {
      if (nums[i] > 0 || (i > 0 && nums[i] == nums[i - 1])) {
        continue
      }
      for (let j = i + 1; j < nums.length; j++) {
        if (j > i + 1 && nums[j] == nums[j - 1]) {
          continue
        }
        for (let k = j + 1; k < nums.length; k++) {
          if (k > j + 1 && nums[k] == nums[k - 1]) {
            continue
          }
          if (nums[i] + nums[j] + nums[k] == 0) {
            res.push([nums[i], nums[j], nums[k]])
          }
        }
      }
    }
    var demo = [...new Set(res.map((i) => JSON.stringify(i)))].map((i) => JSON.parse(i))
    return demo
  };
  nums = nums = [-1, 0, 1, 2, -1, -4]
  // console.log(threeSum(nums))

  // 给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数,使它们的和与 target 最接近。
  // 返回这三个数的和。
  // 假定每组输入只存在恰好一个解。

  //   在数组 nums 中,进行遍历,每遍历一个值利用其下标i,形成一个固定值 nums[i]
  // 再使用前指针指向 start = i + 1 处,后指针指向 end = nums.length - 1 处,也就是结尾处
  // 根据 sum = nums[i] + nums[start] + nums[end] 的结果,判断 sum 与目标 target 的距离,如果更近则更新结果 ans
  // 同时判断 sum 与 target 的大小关系,因为数组有序,如果 sum > target 则 end--,如果 sum < target 则 start++,如果 sum == target 则说明距离为 0 直接返回结果
  var threeSumClosest = function (nums, target) {
    nums.sort((a, b) => a - b)
    var ans = nums[0] + nums[1] + nums[2];
    for (var i = 0; i < nums.length; i++) {
      var start = i + 1,
        end = nums.length - 1;
      while (start < end) {
        var sum = nums[start] + nums[end] + nums[i];
        if (Math.abs(target - sum) < Math.abs(target - ans))
          ans = sum;
        if (sum > target)
          end--;
        else if (sum < target)
          start++;
        else
          return ans;
      }
    }
    return ans;
  }
  nums = [-1, 2, 1, -4], target = 1
  // console.log(threeSumClosest(nums, target))

  // 给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):

  var fourSum = function (nums, target) {
    if (nums.length < 4) return []
    let res = []
    nums.sort((a, b) => a - b)
    for (let i = 0; i < nums.length; i++) {
      if (i > 0 && nums[i] == nums[i - 1]) {
        continue
      }
      for (let j = i + 1; j < nums.length; j++) {
        if (j > i + 1 && nums[j] == nums[j - 1]) {
          continue
        }
        for (let k = j + 1; k < nums.length; k++) {
          if (k > j + 1 && nums[k] == nums[k - 1]) {
            continue
          }
          for (let l = k + 1; l < nums.length; l++) {
            if (l > k + 1 && nums[l] == nums[l - 1]) {
              continue
            }
            if (nums[i] + nums[j] + nums[k] + nums[l] == target) {
              res.push([nums[i], nums[j], nums[k], nums[l]])
            }
          }
        }
      }
    }
    var demo = [...new Set(res.map((i) => JSON.stringify(i)))].map((i) => JSON.parse(i))
    return demo
  };
  nums = [0, 0, 0, 0, 0], target = 0
  // console.log(fourSum(nums, target))

  // 给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
  // 如果数组中不存在目标值 target,返回 [-1, -1]。
  var searchRange = function (nums, target) {

    return [nums.indexOf(target), nums.lastIndexOf(target)]
  };
  nums = [], target = 0
  // console.log(searchRange(nums, target))

</script>

</html>
原文地址:https://www.cnblogs.com/cupid10/p/15617582.html