前端面试拼图-数据结构与算法(二)

摘要:最近,看了下慕课2周刷完n道面试题,记录下...

1. 求一个二叉搜索树的第k小值

        二叉树(Binary Tree)

        是一棵树

        每个节点最多两个子节点

        树节点的数据结构{value, left?, right?}

        二叉树的遍历

        前序遍历:root→left→right

        中序遍历:left→root→right

        后序遍历:left→right→root

        二叉搜索树BST(Binary Search Tree)

        left(包括其后代) value ≤ root value

        right (包括其后代) value ≥ root value

        可使用二分法进行快速查找

        解题思路:BST中序遍历,从小到大的排序

                          找到排序后的第k个值

/**
* 二叉搜索树
*/
interface ITreeNode {
  value: number
  left: ITreeNode | null
  right: ITreeNode | null
}

const arr: number[] = []

/**
* 二叉树前序遍历
*/
function preOrderTraverse(node: ITreeNode | null) {
  if ( node == null) return
  //console.log(node.value)
  arr.push(node.value)
  preOrderTraverse(node.left)
  preOrderTraverse(node.right)
}

/**
* 二叉树中序遍历
*/
function inOrderTraverse(node: ITreeNode | null) {
  if ( node == null) return
  inOrderTraverse(node.left)
  // console.log(node.value)
  arr.push(node.value)
  inOrderTraverse(node.right)
}

/**
* 二叉树后序遍历
*/
function postOrderTraverse(node: ITreeNode | null) {
  if ( node == null) return
  postOrderTraverse(node.left)
  postOrderTraverse(node.right)
  // console.log(node.value)
  arr.push(node.value)
}

/**
* **寻找BST中的第k小值**
*/
function getKthValue(node: ITreeNode, k: number): number | null {
  inOrderTraverse(node)
  console.log(arr)
  return arr[k-1] || null
}

const bst: ITreeNode = {
  value: 5,
  left: {
    value: 3,
    left: {
      value: 2,
      left: null,
      right: null
    },
    right: {
      value: 4,
      left: null,
      right: null
    }
  },
  right: {
      value: 7,
      left: {
        value: 6,
        left: null,
        right: null
      },
      right: {
        value: 8,
        left: null,
        right: null
      }
   }
}

//preOrderTraverse(tree)

平衡二叉树 | HZFE - 剑指前端 Offer题目描述icon-default.png?t=N7T8https://febook.hzfe.org/awesome-interview/book1/algorithm-balanced-binary-trees        扩展:为何二叉树如此重要,而不是三叉树、四叉树?

        性能、性能、还是性能!重要的事情说三遍

        数组:查找快O(1),增删慢O(n);链表:查找慢O(n),增删快O(1)

        二叉搜索树BST:查找快、增删快—"木桶效应"

        平衡二叉树

        BST如果不平衡,那就又成了链表

        所以要尽量平衡:平衡二叉搜索树BBST(其增删查,时间复杂度都是O(logn),即树的高度)

        红黑树:本质是一种自平衡二叉树

        分为红/黑两种颜色,通过颜色转换来维持输的平衡

        相对于普通平衡二叉树,它维持平衡的效率更高

        B树

        物理上是多叉树,但逻辑上是二叉树

        一般用于高效I/O, 关系型数据库常用B树 来组织数据

        扩展2:堆有什么特点?和二叉树又什么关系?

        堆栈模型

        JS执行时,值类型变量,存储在栈中;引用类型变量,存储在堆中

        堆是完全二叉树

        最大堆:父节点 ≥子节点

        最小堆:父节点≤子节点

        满二叉树(又叫完美二叉树):所有层的节点都被填满;

        完全二叉树:最底层节点靠左填充,其它层节点全被填满

7.1   二叉树 - Hello 算法动画图解、一键运行的数据结构与算法教程icon-default.png?t=N7T8https://www.hello-algo.com/chapter_tree/binary_tree/#1_1        逻辑结构 VS 物理结构

        堆:逻辑结构是一颗二叉树,但它的物理结构式一个数组

        堆的使用场景

        特别适合"堆栈模型"

        堆的数据,都是在栈中引用的,不需要从root遍历

        堆恰巧是数组形式,根据栈的地址,可用O(1)找到目标

2. JS计算斐波那契数列的第n个值

/**
* 斐波那契额数列(递归)
*/
function fibonacci(n:number): number{
  if(n <=1 ) return n
  return fibonacci(n-1) + fibonacci(n-2)
}

        递归有大量重复计算,其时间复杂度是O(2^n)

        优化:不用递归用循环,记录中间结果,时间复杂度O(n)

/**
* 斐波那契额数列(循环)
*/
function fibonacci(n:number): number{
  if(n <=1 ) return n
  let n1 = 1  //记录n-1的结果
  let n2 = 0  //记录n-2的结果
  let res = 0
  
  for(let i = 2; i <= n; i++) {
    res = n1 + n2;
    // 记录中间结果
    n2 = n1
    n1 = res
  } 
  return res
}

        动态规划:

        把一个大问题,拆解为一个小问题,逐级向下拆解

        用递归的思想去分析问题,再改用循环来实现

        算法三大思维:贪心、二分、动态规划

        扩展:青蛙跳台阶问题,一只青蛙,一次可跳1级,也可跳两级,请问青蛙跳到n级台阶,总共有多少种方式?

        第一次跳1级则有f(n-1)种方式,跳2级则有f(n-2)种方式,则结果和斐波那契额数列一样。

3. 将数组的0 移动到末尾

        如输入[1,0,3,0,11,0],输出[1,3,11,0,0,0],只移动0,其他顺序不变;必须在原数组进行操作

        传统思路

        遍历数组,遇到0则push到数组末尾

        用splice截取当前元素

        时间复杂度O(n^2)—算法不可用

        数组是连续存储,要慎用splice unshift 等API

/**
* 移动0到数组末尾(嵌套循环)
*/
function moveZero1(arr:number[]):void {
  const length = arr.length
  if(length === 0) return
  
  let zeroLength = 0
  // **O(n^2)**
  for (let i = 0; i < length - zeroLength; i++) {
    if (arr[i] === 0) {
      arr.push(0)
      arr.splice(i,1)  // 本身就有O(n)
      i-- //数组接去了一个元素,i要递减,否则连续0就会有错误
      zeroLength++ // 累加0的长度
    }
  }
}

        双指针思路(解决嵌套循环的有效)

        定义j指向第一个0,i指向j后面的第一个非0

        交换i和j的值,继续向后移动

        只遍历一次,所以时间复杂度是O(n)

/**
* 移动0到数组末尾(双指针)
*/
function moveZero2(arr:number[]):void {
  const length = arr.length
  if(length === 0) return
  
  let i
  let j = -1 // 指向第一个0
  for(i=0; i < length; i++) {
    if(arr[i] === 0) {
      if (j < 0) {   // 第一个0
        j = i
      }
    }
    if(arr[i] !== 0 && j >=0 ) {
      const n = arr[i]
      arr[i] = arr[j]
      arr[j] = n
      j++
    }
  }
}

4. 获取字符串中连续最多的字符,以及次数

        如输入'abbcccddeeee1234',计算得到连输最多的字符是'e',为4次

        传统思路

        嵌套循环,找出每个字符的连续次数,并记录

        看似时间复杂度是O(n^2)

        但实际时间复杂度是多少?—O(n),因为有'跳步'

/**
* 求连续最多的字符和次数(嵌套循环)
*/
interface IRes {
  char: string
  length: number
}
function findContinuousChars1(str:string):IRes {
  const res:IRes = {
    char: '',
    length: 0
  }
  const length = str.length
  if (length === 0) return res
  
  let tempLength = 0 //临时记录当前连续字符串的长度
  // 时间复杂度O(n)
  for(let i = 0; i < length; i++) {
    tempLength = 0 // 重置
    for(let j = i; j < length; j++) {
      if (str[i] === str[j]) {
        tempLength++
      }
      if(str[i] !== str[j] || j === length-1) {
        // 不相等,或者已经到最后一个元素。要去判断最大值
        if (tempLength > res.length) {
          res.char = str[i]
          res.length = tempLength
        }
        if (i < length - 1) {
          i = j -1   // 跳步
        }
        break
      }
    }
  }  
  return res
}

        双指针思路(适用于解决嵌套循环类问题)

        定义指针i和j;j不动,i继续移动

        如果i和j的值一直相等,则i继续移动

        直到i和j的值不相等,记录处理,让j追上i。继续第一步

/**
* 求连续最多的字符和次数(双指针)
*/
interface IRes {
  char: string
  length: number
}
function findContinuousChars2(str:string):IRes {
  const res:IRes = {
    char: '',
    length: 0
  }
  const length = str.length
  if (length === 0) return res
  
  let tempLength = 0 //临时记录当前连续字符串的长度
  // 时间复杂度O(n)
  let i = 0
  let j = 0
  for(; i < length; i++) {
    if(str[i] === str[j]) {
      tempLength++
    }
    if(str[i] !== str[j] || i === length-1) {
      // 不相等,或者i到了字符串的末尾
      if(tempLength > res.length) {
        res.char = str[j]
        res.length = tempLength
      }
      tempLength = 0  //重置长度
      
      if(i < length - 1) {
        j = i //让j"追上" i
        i--
      }
    }
  }
 
  return res
}

ps:算法题尽量使用低级的代码,慎用语法糖或者高级API

5. 用JS实现快速排序,并说明时间复杂度

6. 获取1-10000之前所有的对称数

7. 如何实现高效的英文单词前缀匹配

未完待续……

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/490806.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ArcGIS:焦点统计权重weight的设置方法

ArcGIS中的焦点统计可以用于计算指定邻域大小内的统计值&#xff0c;并重新赋给中心像元。其中可以通过未邻域内每个元素赋权重新计算&#xff0c;下面介绍下如何设置核文件。 1、新建一个txt文件 2、在txt里面写好权重&#xff0c;按照ArcGIS里面的帮助&#xff0c;3*3窗口如…

树和森林解析

01.下列关于树的说法中&#xff0c;正确的是&#xff08;D). Ⅰ.对于有n个结点的二叉树&#xff0c;其高度为log2n Ⅱ.完全二叉树中&#xff0c;若一个结点没有左孩子&#xff0c;则它必是叶结点 Ⅲ.高度为h (h>0)的完全二叉树对应的森林所含的树的个数一定是h IV.一棵树中的…

Python中的数据类型有四类八种如何理解?

在Python中&#xff0c;数据类型大致可以分为四大类&#xff0c;包含了八种基本的数据类型&#xff0c;这些分类有助于理解和使用Python进行编程。这四大类分别是&#xff1a; 数字类型 (Numeric Types): 整型 (int): 表示没有小数部分的整数&#xff0c;可以是正数、负数或零。…

2024年【熔化焊接与热切割】考试报名及熔化焊接与热切割找解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 熔化焊接与热切割考试报名考前必练&#xff01;安全生产模拟考试一点通每个月更新熔化焊接与热切割找解析题目及答案&#xff01;多做几遍&#xff0c;其实通过熔化焊接与热切割实操考试视频很简单。 1、【单选题】 下…

nandgame中的控制单元(Control Unit)

关卡说明的翻译&#xff1a; 控制单元除了ALU指令之外&#xff0c;计算机还应支持数据指令。在数据指令中&#xff0c;指令值直接写入A寄存器。创建一个控制单元&#xff0c;根据指令I的高位执行数据指令或ALU指令&#xff1a;位 15 0 数据指令 1 ALU指令ALU指令 对于ALU指令&…

一阶低通滤波

一阶低通滤波是一种信号处理技术&#xff0c;用于去除信号中高频部分&#xff0c;保留低频部分。在滤波过程中&#xff0c;一阶低通滤波器会使得高于某个截止频率的信号被衰减&#xff0c;而低于截止频率的信号则会被保留。这有助于减少噪音或者不需要的信号成分&#xff0c;从…

前端小白的学习之路(webpack)

提示&#xff1a;webpack简介&#xff0c;nvm,npm配置环境,常用命令&#xff0c;基本web项目构建 目录 webpack 1.配置环境 1)node.js node常用命令 2)nvm nvm常用命令&#xff1a; 3)npm npm常用命令 2.构建简易web项目 1)创建目录 2)安装webpack依赖 3)配置 webpac…

nandgame中的复合存储器

output部分的三个寄存器是用于校验结果的&#xff0c; 实际还得摆放寄存器A、D和RAM 然后st都是触发导通&#xff0c;cl都是触发传值&#xff0c; ad是address的缩写 *a是c语言的写法&#xff0c;a为地址&#xff0c;*a就是地址a指向位置存储的数值。

C语言之strchr用法实例(八十八)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

代码随想录算法训练营第二十天|654.最大二叉树、617.合并二叉树、700.二叉搜索树中的搜索、98.验证二叉搜索树

代码随想录算法训练营第二十天|654.最大二叉树、617.合并二叉树、700.二叉搜索树中的搜索、98.验证二叉搜索树 654.最大二叉树 给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建: 创建一个根节点&#xff0c;其值为 nums 中的最大值。递归地…

vue项目使用eletron将打包成桌面应用(.exe)

vue项目使用eletron将打包成桌面应用(.exe) 1.前期准备 两个项目&#xff1a; 1、自己用vue cli创建的项目 2、第二个是去gitee将案例clone下来 案例地址 https://gitee.com/qingplus/electron-quick-start.git 2、测试案例是否可以正常运行 # 进入项目 cd electron-quick-…

k8s入门到实战(六)—— ConfigMap介绍

ConfigMap configmap 是 k8s 中的资源对象&#xff0c;用于保存非机密性的配置的&#xff0c;数据可以用 kv 键值对的形式保存&#xff0c;也可通过文件的形式保存。 什么是 configmap 在 k8s 中&#xff0c;ConfigMap 是一种用于存储应用程序配置数据的对象。它允许将配置信…

JVM(三)——字节码技术

三、字节码技术 1、类文件结构 一个简单的 HelloWorld.java package com.mysite.jvm.t5; // HelloWorld 示例 public class HelloWorld {public static void main(String[] args) {System.out.println("hello world");} }执行 javac -parameters -d . HellowWorld.…

家用洗地机什么牌子好?2024四款家用洗地机良心推荐

洗地机集合了吸拖扫为一体的清洁设备&#xff0c;可以吸走灰尘&#xff0c;吸走污渍&#xff0c;还能杀菌等等&#xff0c;高效清洁又省力&#xff01;对于工作忙的上班族&#xff0c;带娃的宝妈&#xff0c;还有体弱的老人都非常适合。但是说到选购产品这方面&#xff0c;很多…

leetcode mt simple

Leetcode-MT-Simple 文章实际写于2021年&#xff0c;那个炎热的夏天。 Leet Code 美团题库简单类总结&#xff0c;题目按照解法可大致分为数学法、计数法、位运算、双指针法、字符串、哈希表、栈、递归/迭代、排序法、匹配法、记忆化法、二分法、分治法、摩尔投票法、前缀和、…

头条网盘如何快速获取授权推广

近期可以说是网盘拉新的一个盛宴&#xff0c;好几家网盘为了抢夺用户&#xff0c;都在付费拉新用户&#xff0c;而如今头条网盘也需要开拓市场&#xff0c;方式也很简单粗暴&#xff0c;就是拿钱砸&#xff0c;而对于普通用户来说&#xff0c;只要获得授权&#xff0c;正是赚钱…

NVIDIA A100 NVLink 和 NVIDIA A100 PCIe的区别?

NVIDIA A100 NVLink 和 NVIDIA A100 PCIe 是两种不同连接方式的 NVIDIA A100 GPU。 NVIDIA A100 NVLink: 这种版本的 A100 GPU 使用 NVLink 连接方式&#xff0c;可以实现更高的带宽和更低的延迟。NVLink 是 NVIDIA 的一种专有连接技术&#xff0c;用于连接多个 GPU&#xff0c…

方案功能开发:智能机器人玩具

玩具电动趣萌机器人方案开发定制&#xff0c;东莞市酷得智能科技有限公司是研发型芯片贸易公司&#xff0c;可为制造厂商朋友定制软件底层方案。下面介绍一下机器人方案可实现的功能&#xff1a; 基础功能&#xff1a; 方向&#xff1a;前进&#xff0c;后退&#xff0c;左转&a…

10分钟搭建一套代码质量监控平台

01、jenkins安装部署 01、Jenkins下载 中文官网地址&#xff1a;https://www.jenkins.io/zh/ 02、Jenkins环境安装 安装jdk&#xff0c;上传jenkins安装包&#xff0c;启动jenkins&#xff0c;耐心等待启动完成(第一次需要个几分钟) java -jar jenkins.war 执行日志里一定…

JAVA面试大全之集合IO篇

目录 1、集合 1.1、Collection 1.1.1、集合有哪些类&#xff1f; 1.1.2、ArrayList的底层&#xff1f; 1.1.3、ArrayList自动扩容&#xff1f; 1.1.4、ArrayList的Fail-Fast机制&#xff1f; 1.2、MAP 1.2.1、Map有哪些类&#xff1f; 1.2.2、JDK7 HashMap如何实现…