算法杂记(六)

149 阅读1分钟

「这是我参与2022首次更文挑战的第13天,活动详情查看:2022首次更文挑战

快速排序

题目信息

这题在力扣是算法题,这里主要就快排做讨论

解法一

阮一峰老师10年前写的,但是空间复杂度比较大,力扣没过,也贴一下。

var sortArray = function(nums) {
    if(nums.length < 2) return nums
    let pivot = 0
    let left = []
    let right = []
    for(let i = 1 ; i < nums.length;i++){
        if(nums[i] > nums[pivot]){
            right.push(nums[i])
        }else{
            left.push(nums[i])
        }
    }
    return sortArray(left).concat([nums[0]],sortArray(right))
};

解法二

原地快排

原地快排主要是在原数组中进行修改,原理还是,确定一个枢轴,枢轴的左边是比枢轴小的值,右边是比枢轴大的值,之后再重复对左右的枢轴做这样的操作,直到当左右部分只剩下一个元素时,则说明当前部分已经排序完成。

var sortArray = function(nums) {
    if (nums.length < 2) return nums;
    return  quick(nums, 0, nums.length - 1);
};

function quick(nums,left,right){
    if(nums.length > 1){
        let index = partition(nums,left,right)
        if(left < index-1){
        quick(nums,left,index-1)
        }
        if(index < right){
            quick(nums,index,right)
        }
    }
    return nums
}

function partition(nums,left,right){
    let p = nums[Math.floor((left+right) / 2)]
    while(left <= right){
        while(nums[left] < p){
            left++
        }
        while(nums[right] > p){
            right--
        }
        if(left <= right){
            [nums[left],nums[right]] = [nums[right],nums[left]]
            left++
            right--
        }
    }
    return left
}

求根节点到叶子节点数字之和

题目信息

解法一

广度优先

维护两个队列,一个放置节点,一个放置节点对应的值,先将根节点入队。之后开始遍历队列,节点和数值出队,如果节点是叶子节点,没有左子树也没有右子树,即总和加上该节点保存的总值。如果不是,则将该接待你的子节点加入节点队列,再计算对应数值,为当前节点的值乘10再加上孩子节点的值。

var sumNumbers = function (root) {
  if (root.left === null && root.right === null) return root.val
  let nodeQueue = [root]
  let numQueue = [root.val]
  let sum = 0
  while (nodeQueue.length > 0) {
      let node = nodeQueue.shift()
      let num = numQueue.shift()
      if(node.left === null && node.right === null){
          sum+=num
      }else{
        if (node.left) {
            nodeQueue.push(node.left)
            numQueue.push(num * 10 + node.left.val)
          }
          if (node.right) {
            nodeQueue.push(node.right)
            numQueue.push(num * 10 + node.right.val)
          }
      }
  }
  return sum
}

解法二

深度优先

定义一个深度优先函数,传入当前节点与父节点的总值,计算该节点的总值,如果是叶子节点返回总值,否则再递归球的左孩子和有孩子的总值。

var sumNumbers = function (root) {
    function dfs(node,preSum){
        if(node === null) return 0
        let sum = preSum*10 + node.val
        if(node.left === null && node.right === null){
            return sum
        }else{
            return dfs(node.left,sum) + dfs(node.right,sum)
        }
    }

    return dfs(root,0)
}