17.电话号码的字母组合:
题目描述:
实现思路:
将回溯过程抽象成树结构,每个叶子节点作为结果的一部分。
我们定义一个数组map,它的下标表示输入的数字所对应的字母,先对特殊情况进行处理:1.输入为空,则直接返回一个空数组。2. 输入为一个,则直接通过 split() 方法返回:map[digits].split("");
之后写定义 backtraking 函数,传入digits ,digits的长度,0。path表示节点,如果path的长度等于输入数字的长度就将path的结果放入res数组中。通过 for..of 循环来取出字母加入到 path 中。
代码:
var letterCombinations = function(digits) {const k = digits.lengthconst map = ["","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"]if(!k) return []if(k === 1) return map[digits].split("");const res = []const path = []backtraking(digits,k,0)return resfunction backtraking(digits,k,i){if(path.length === k){res.push(path.join(""));return}for(const j of map[digits[i]]){path.push(j)backtraking(digits,k,i+1)path.pop()}}
};
20.有效的括号:
题目描述:
实现思路:
通过栈来实现,每次遍历使用switch语句来处理:
-
如果
c
是左小括号(
,则将右小括号)
压入栈中。 -
如果
c
是左中括号[
,则将右中括号]
压入栈中。 -
如果
c
是左大括号{
,则将右大括号}
压入栈中。 -
如果
c
不是左括号(即c
是右括号),则尝试与栈顶的括号匹配。如果不匹配,或者栈为空(意味着没有对应的左括号),则返回false
。
代码:
var isValid = function(s) {let stack = [];for(let i = 0;i < s.length;i++){switch(s[i]){case '(':stack.push(')');break;case '{':stack.push('}');break;case '[':stack.push(']');break;default:if(s[i] !== stack.pop()){return false;}}}return stack.length === 0
};
53.最大子数组和:
题目描述:
实现思路:
初始化一个变量 result
,用来存储遍历过程中遇到的最大子数组和。初始值设为 -Infinity
是为了确保任何实际的子数组和都会大于这个初始值。遍历数组,将当前元素 nums[i]
加到 count
上,即计算当前考察的子数组的和。如果当前子数组的和(count
)大于迄今为止找到的最大子数组和(result
),则更新 result
。如果当前子数组的和变为负数,则重置 count
为0,因为负数会减小后续元素的和,所以从下一个元素开始重新计算子数组的和可能得到更大的结果。
代码:
var maxSubArray = function(nums) {let result = -Infinitylet count = 0for(let i = 0;i < nums.length;i++){count += nums[i]if(count > result){result = count}if(count < 0) {count = 0}}return result
};
78.子集:
题目描述:
实现思路:
将回溯过程抽象成树结构,每个叶子节点作为结果的一部分。
这一题的重点是知道每一个节点都是作为结果的一部分,并且集合是无序的,[1,2]和[2,1] 是一样的,取过的元素不能取,我们通过下标与 for 循环,取过的下标不能再继续取,所以从 startIndex
开始。
代码:
var subsets = function(nums) {let result = []let path = []backtracking(0)function backtracking (startIndex){result.push([...path])for(let i = startIndex ; i < nums.length ; i++){path.push(nums[i])backtracking(i+1)path.pop()}}return result
};
215.数组中的第k个最大元素:
题目描述:
实现思路:
这一题用堆排序,将无序序列构建成一个堆,根据升序降序需求选择大顶堆将堆顶元素与末尾元素交换,将最大元素「沉」到数组末端重新调整结构,使其满足堆定义,然后继续交换堆顶与当前末尾元素,反复执行调整、交换步骤,直到整个序列有序。
代码:
var findKthLargest = function(nums, k) {let heapSize = nums.lengthbuildMaxHeap(nums,heapSize)for(let i = nums.length - 1;i >= nums.length - k + 1;i--){swap(nums,i,0)heapSize--;maxHeapify(nums,0,heapSize)}return nums[0]function buildMaxHeap(nums,heapSize){//从最后一个非叶子节点开始for(let i = Math.floor(heapSize/2) - 1; i >= 0 ;i--){maxHeapify(nums,i,heapSize)}}function maxHeapify(nums,i,heapSize){let l = i * 2 + 1;let r = i * 2 + 2;let largest = i;if(l < heapSize && nums[l]>nums[largest]){largest = l}if(r < heapSize && nums[r]>nums[largest]){largest = r}// 判断根节点是否为i,根节点要比两个子节点要大if(largest !== i){swap(nums,i,largest)maxHeapify(nums,largest,heapSize)}}function swap(nums,i,largest){let temp = nums[i]nums[i] = nums[largest]nums[largest] = temp}};