2021-10-21

栈D:\前端\新建文件夹\前后端\vue-shop-admin\api接口文档.md

// 栈的封装
// 栈类
function Stack() {
  this.item = []
  Stack.prototype.push = function (element) {
    this.items.push(items)
  }
  Stack.prototype.pop = function () {
    return this.items.pop()
  }
  Stack.prototype.peek = function () {
    return this.items[items.length - 1]
  }
  Stack.prototype.isEmpty = function () {
    return this.items.length == 0
  }
  Stack.prototype.size = function () {
    return this.items.length
  }
  Stack.prototype.toString = function () {
    var resultString = ''
    for (let i = 0; i < this.items.length; i++) {
      resultString += this.items[i] + ''
    }
    return resultString
  }
}
// function Stack() {
//   var items = []
//   //压栈
//   this.push = function (element) {
//     items.push(element)
//   }
//   // 出栈
//   this.pop = function () {
//     return items.pop()
//   }
//   // peek操作
//   this.peek = function () {
//     return items[items.length - 1]
//   }
//   // 判断栈中元素是否为空
//   this.isEmpty = function () {
//     return items.length == 0
//   }
//   // 获取栈中元素的个数
//   this.size = function () {
//     return items.length
//   }
// }
var stack = new Stack()
stack.push(1);
console.log('1');
// --------
// 十进制转二进制
function dec2bin(decNumber) {
  var stack = new Stack()
  var remainder
  while (decNumber) {
    remainder = decNumber % 2;
    decNumber = Math.floor(decNumber / 2)
    stack.push(remainder)
  }
  var binayriString = "1"
  while (!stack.isEmpty) {
    binayriString += stack.pop()
  }
  return binayriString;
}

// console.log(stack);

队列

// 自定义队列
function Queue(){
  var items=[]
  // 向队列尾部添加一个多多个新的项
  this.enqueue=function (element){
    items.push(element)
  }
  // 移除队列中第一个元素,并返回被移除的元素
  this.dequeue=function(){
    return items.shift()
    }

  // 返回队列中第一个元素,最先被添加,也将是最先被移除的元素
  this.front=function(){
    return items[0]
  }
  this.isEmpty=function(){
    return this.length==0
  }
  this.size=function(){
    return items.length
  }
}
var queue=new Queue()
// --------
// 优先级队列
function PriorityQueue(){
var items=[]
// 封装一个新的构造函数,用于保存元素和元素的优先级
function QueueElement(element,priority){
  this.element=element
  this.priority=priority
}
// 添加元素的方法
this.enqueue=function(element,priority){
// 根据传入的元素,创建新的QueueElement
var queueElement=new QueueElement(element,priority)
if(this.isEmpty()){
items.push(queueElement)
}
else{
  var add=false
  for(let i=0;i1){
  for(let i=0;i

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eeSxRAbj-1634807680133)(算法题练习.assets/image-20210628005037435.png)]

链表

// 封装链表的构造函数
function LinkedList() {
  // 封装一个Node类, 用于保存每个节点信息
  function Node(element) {
    this.element = element
    this.next = null
  }

  // 链表中的属性
  this.length = 0
  this.head = null

  // 链表尾部追加元素方法
  LinkedList.prototype.append = function (element) {
    // 1.根据新元素创建节点
    var newNode = new Node(element)

    // 2.判断原来链表是否为空
    if (this.head === null) { // 链表尾空
      this.head = newNode
    } else { // 链表不为空
      // 2.1.定义变量, 保存当前找到的节点
      var current = this.head
      while (current.next) {
        current = current.next
      }

      // 2.2.找到最后一项, 将其next赋值为node
      current.next = newNode
    }

    // 3.链表长度增加1
    this.length++
  }

  // 链表的toString方法
  LinkedList.prototype.toString = function () {
    // 1.定义两个变量
    var current = this.head
    var listString = ""

    // 2.循环获取链表中所有的元素
    while (current) {
      listString += "," + current.element
      current = current.next
    }

    // 3.返回最终结果
    return listString.slice(1)
  }

  // 根据下标删除元素
  LinkedList.prototype.insert = function (position, element) {
    // 1.检测越界问题: 越界插入失败
    if (position < 0 || position > this.length) return false

    // 2.定义变量, 保存信息
    var newNode = new Node(element)
    var current = this.head
    var previous = null
    index = 0

    // 3.判断是否列表是否在第一个位置插入
    if (position == 0) {
      newNode.next = current
      this.head = newNode
    } else {
      while (index++ < position) {
        previous = current
        current = current.next
      }

      newNode.next = current
      previous.next = newNode
    }

    // 4.length+1
    this.length++

    return true
  }

  // 根据位置移除节点
  LinkedList.prototype.removeAt = function (position) {
    // 1.检测越界问题: 越界移除失败, 返回null
    if (position < 0 || position >= this.length) return null

    // 2.定义变量, 保存信息
    var current = this.head
    var previous = null
    var index = 0

    // 3.判断是否是移除第一项
    if (position === 0) {
      this.head = current.next
    } else {
      while (index++ < position) {
        previous = current
        current = current.next
      }

      previous.next = current.next
    }

    // 4.length-1
    this.length--

    // 5.返回移除的数据
    return current.element
  }

  // 根据元素获取链表中的位置
  LinkedList.prototype.indexOf = function (element) {
    // 1.定义变量, 保存信息
    var current = this.head
    index = 0

    // 2.找到元素所在的位置
    while (current) {
      if (current.element === element) {
        return index
      }
      index++
      current = current.next
    }

    // 3.来到这个位置, 说明没有找到, 则返回-1
    return -1
  }

  // 根据元素删除信息
  LinkedList.prototype.remove = function (element) {
    var index = this.indexOf(element)
    return this.removeAt(index)
  }

  // 判断链表是否为空
  LinkedList.prototype.isEmpty = function () {
    return this.length == 0
  }

  // 获取链表的长度
  LinkedList.prototype.size = function () {
    return this.length
  }

  // 获取第一个节点
  LinkedList.prototype.getFirst = function () {
    return this.head.element
  }
}

1. 二分查找算法

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。nums = [-1,0,3,5,9,12], target = 9

思路:

  • 如果目标值等于中间值,则找到元素。

  • 如果目标值比中间值小,则向左侧搜索

  • 如果目标值比中间值大,则向右侧搜索

    算法:初始化left=0,right=nums.length-1;

    当left<=right时;比较中间元素nums[mid]与目标值target值。

    • 如果target=nums[mid],则直接return mid
    • 如果target>nums[mid],则left=mid+1;
    • 其他,right=mid-1;

代码:

let midparse=funtion(nums,target) {
let left=0;
let right=nums.length-1;
while(left<=right){
let mid=Math.floor((left+right)/2);
if(target==nums[mid]){
return mid;
}
if(target>nums[mid]){
left=mid+1;
}
else{
right=mid-1;
}
}
return -1;
}
let a=[1,2,3,4,5];
midparse(a,3);

2. 数的翻转

X=123,3=123%10,res=0,res=res * 10 + x % 10

12=123/10,2=12%10,1=12/10

var reverse = function(x) {
 
    let res = 0;
    while(x>0){
        res = res * 10 + x % 10;
        if(res > Math.pow(2, 31) - 1 || res < Math.pow(-2, 31)) return 0;
        x = ~~(x / 10);
    }
    return res;
}
--------
let a = 123456
function x(num) {
  let res = 0
  while (Math.floor(num / 10) > 0) {
    res = res * 10 + num % 10
    console.log(res);
    num = Math.floor(num / 10)
    if (num < 10) {
      res = res * 10 + num % 10
    }
    console.log(num);
  }
  return res
}
console.log(x(a));

3. 两数之和

输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1]

var twoSum=funtion(nums,target){
var map =new Map();
for(let i=0;i<nums.length;i++){
let temp=target-nums[i];
if(map.has(temp)){
return [map.get(temp),i]//i=1,nums[i]=7,输出[0,1]
}
else{
    map.set[nums[i],i]//i=0,map: [2:0]
}
}
}

4. 两数相加

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sFo0L3yi-1634807680136)(算法题练习.assets/image-20210612233507801.png)]

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字

输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
//构造一个链表节点函数(JavaScript本身没有链表这个数据结构,自己用构造函数实现)
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
 function ListNode(val, next) {
      this.val = (val===undefined ? 0 : val)
     this.next = (next===undefined ? null : next)
  }
var addTwoNumbers = function(l1, l2) {
let dummy=new ListNode();//定义一个新链表头结点,用来占位
let curr=dummy;//用来一步步往下走的
let carry=0;//处理进位
while(l1!=null||l2!=null){
    let sum=0;
    if(l1!=null){
        sum+=l1.val;
        l1=l1.next;
    }
    if(l2!=null){
        sum+=l2.val;
        l2=l2.next;
    }
    sum+=carry;//sum先加上一个的进位
    curr.next=new ListNode(sum%10);//把和求余放在新节点上
    carry=Math.floor(sum/10);//新的进位,向下取整
    curr=curr.next;//指针向下移
}
if(carry>0){
    curr.next=new ListNode(carry);//表尾之和大于0,需要进位,循环结束,把carry加到新节点。
}
return dummy.next;

};

5. 三数之和

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gkOGOoxo-1634807680139)(算法题练习.assets/image-20210615165432899.png)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AD7RnL9Z-1634807680141)(算法题练习.assets/image-20210615170214676.png)]

var threeSum = function(nums) {
    let result=[];
    nums.sort((a,b)=>a-b);
    for(let i=0;i

6.删除链表倒数第N个节点

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-efksiYjY-1634807680142)(算法题练习.assets/image-20210615172457849.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SUk9NPz8-1634807680142)(算法题练习.assets/image-20210615172437528.png)]

var removeNthFromEnd=function(head,n){
    let dummy=new listNode();
    let n1=dummy;
    let n2=dummy;
    dummy.next=head;
    for(let i=0;i<=n;i++){
        n2=n2.next;
    }
    while(n1!=null&&n2!=null){
        n1=n1.next;
        n2=n2.next;
    }
    n1.next=n1.next.next;
    return dummy.next
}

7. 有效括号匹配

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qy7tB09F-1634807680143)(算法题练习.assets/image-20210615235305461.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-djfMer2r-1634807680143)(算法题练习.assets/image-20210615235326043.png)]

var isValid = function(s) {
    let stack=[];
let map =new Map();
map.set("{","}");
map.set("(",")");
map.set("[","]");
for(let i=0;i

8. 合并有序链表

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B12BA2AJ-1634807680144)(算法题练习.assets/image-20210616133228815.png)]

 * 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 mergeTwoLists = function(l1, l2) {
let dummy=new ListNode();
let curr=dummy;
while(l1!=null&&l2!=null){
    if(l1.val<l2.val){//把较小的值添加到新链表中,向后移动较小值所在的链表,继续比较
        curr.next=l1;
        l1=l1.next;
    }
    else{//如果L2链表值更小,则加入到新链表中
        curr.next=l2;
        l2=l2.next;
    }
    curr=curr.next//遍历指针下移,
}
if(l1!=null){//如果一个链表为空了,则比较结束,把剩下的直接加入到链表中
    curr.next=l1;
}
if(l2!=null){
    curr.next=l2;
}
return dummy.next;//合并结束,返回新链表
};

9. 两两交换链表中的节点

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-S77hBG9L-1634807680145)(算法题练习.assets/image-20210616135750713.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Fqn0D6Da-1634807680145)(算法题练习.assets/image-20210616135806576.png)]

var swapPairs = function(head) {
let dummy=new ListNode();//声明一个头结点
let curr=dummy;
dummy.next=head;//指向新链表
while(curr.next!=null&&curr.next.next!=null){//重点是正确调换指针指向
    let n1=curr.next;
    let n2=curr.next.next;
    curr.next=n2;
    n1.next=n2.next;
    n2.next=n1;
    curr=n1;//这里指针不是往下移动一个(curr.next),而是指向交换后的第二个节点,这样才能保证n1,n2是下一次交换的两个节点。
}
return dummy.next;
};

10. 无重复字符串的最大长度

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NPgmxREW-1634807680146)(算法题练习.assets/image-20210616142949351.png)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5PfPqJce-1634807680147)(算法题练习.assets/image-20210616143110334.png)]

var lengthOfLongestSubstring = function(s) {
let set =new Set();//声明一个set集合
let maxLength=0;
let j=0;
for(let i=0;i

11. 最大回文字符串

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YCBmRgm7-1634807680148)(算法题练习.assets/image-20210616151043062.png)]

var longestPalindrome = function(s) {
if(s.length<2){
    return s;
}
let start=0;
let maxLength=1;
function expandAroundCenter(left,right){
    while(left>=0&&rightmaxLength)
{start=left;
    maxLength=right-left+1;

}//长度是否更新,都应该继续向两边扩散
left--;
right++;
    }
}
for(let i=0;i

12. 字母异位词分组

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GSyjKdY8-1634807680149)(算法题练习.assets/image-20210617143155323.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7LWfv5MJ-1634807680149)(算法题练习.assets/image-20210617143122106.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qce3dSpz-1634807680149)(算法题练习.assets/image-20210617143327015.png)]

var groupAnagrams = function(strs) {
    if(strs.length===0){
        return [] ;
    } 
    const map=new Map();//建立一个map,key为相同单词的标识,value为标识所对应的单词
for(const str of strs){
    const characters= Array(26).fill(0);//建立一个用于标识拥有相同字母的单词,不能加new。
    for(let i=0;i

13. 最大子序和

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FyAsqcjV-1634807680150)(算法题练习.assets/image-20210617151235325.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-unozZvj2-1634807680151)(算法题练习.assets/image-20210617151319495.png)]

var maxSubArray = function(nums) {
const demo=[];
demo[0]=nums[0];//第一个数组存放的和
for(let i=1;i

14. 螺旋矩阵

![]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FVHxWKXc-1634807680151)(算法题练习.assets/image-20210617162110232.png)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DUIwKQwi-1634807680152)(算法题练习.assets/image-20210617163235747.png)]

/**
 * @param {number[][]} matrix
 * @return {number[]}
 */
//思路:确定边界,上下左右的边界,顺时针就是按照方向→↓←↑的顺序
var spiralOrder = function(matrix) {
let left=0;
let bottom=matrix.length-1;
let top=0;
let right=matrix[0].length-1;
let direction="right";
let result=[];
while(left<=right&&top<=bottom){//为什么可以等于,因为每一次遍历都是使各个方向加一或减一,如果不相等的话,后面会有元素遍历不到
    if(direction=="right"){
    for(let i=left;i<=right;i++){
    result.push(matrix[top][i]);
    }
top++;//向右遍历了第一行,则top加一,作为下一次遍历的起始位置
direction="bottom"//下一次遍历的方向
    }
    else if(direction=="bottom"){
        for(let i=top;i<=bottom;i++){
            result.push(matrix[i][right]);
        }
        right--;//最右一列遍历结束,则right减一,作为下次向左遍历的起始位置
        direction="left";
    }
    else if(direction=="left"){
        for(let i=right;i>=left;i--){
            result.push(matrix[bottom][i]);
        }
        bottom--;
        direction="top";
    }
    else if(direction=="top"){
        for(let i=bottom;i>=top;i--){
            result.push(matrix[i][left]);
        }
        left++;
        direction="right";
    }
}
return result;
};

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7j0pAT6f-1634807680153)(算法题练习.assets/image-20210617163645379.png)]

15. 合并区间

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Vs8pGX4q-1634807680153)(算法题练习.assets/image-20210617171257364.png)]

var merge = function(intervals) {
    if(intervals.length<2){
        return intervals;
    }
intervals.sort((a,b)=>
  a[0]-b[0]
)//先排序,按照区间从小到大排序,只有一句代码可以省略return和{}。
let cos=intervals[0];//把第一个区间作为参照
let result=[];
for(let interval of intervals){//遍历数组中所有区间
if(cos[1]>=interval[0]){//如果第一个区间的末尾数比第二个区间的开始值要大,则说明可以合并,合并的新区间是两个区间的末尾最大值
    cos[1]=Math.max(cos[1],interval[1]);
}
else{//如果前一个区间末尾数比下一个区间的开始值要小,则说明不可合并,先把上一个区间添加到result中,把该区间作为下一个的参照区间,继续比较
    result.push(cos);
    cos=interval;
}}
if(cos.length!=0){//比较到最后两个区间,如果可以合并,在条件判断中并没有加入到result中,则需要在这里把最后可以合并的区间添加到result中
     result.push(cos);
}

return result;
};

16. 数组加一

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r1UD7WRl-1634807680154)(算法题练习.assets/image-20210617232735493.png)]

var plusOne = function(digits) {
for(let i=digits.length-1;i>=0;i--){//1. 123+1=124,119+1=120,199+1=200,当不是所有都是9的时候,如果该数是9,则变成0,前一位不为9的数加一,则得出结果,如果都不是9,则直接末尾数加一得出结果
    if(digits[i]!=9){
        digits[i]++;
        return digits;
    }else{
        digits[i]=0;
    }
}
//2. 排除以上结果,下面都是为9的数,例如,999+1=1000,则执行上面的条件后,把等于9的数都变成0,最后在前面加上1,用数组连接上,则得出结果
const result=[1,...digits];
return result;
};

17. 爬楼梯

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6CqZjke8-1634807680155)(算法题练习.assets/image-20210617234532928.png)]

var climbStairs = function(n) {//注意是爬n阶楼梯的方法,而不是步数,
    let demo=[];
 demo[1]=1;
demo[2]=2;//有规律可以得出,爬n阶楼梯的方法跟爬前两阶楼梯的方法有关,并且使前两阶方法之和
for(let i=3;i<=n;i++){//必须可以等于n,不然当n等于3的时候会循环不成立,
    demo[i]=demo[i-2]+demo[i-1];
}
return demo[n];//这里是直接输出第n项的值,而不是demo数组。

};

18. 删除链表中相等的数2

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7TVTBjH4-1634807680155)(算法题练习.assets/image-20210618133050040.png)]

function ListNode(val, next) {
      this.val = (val===undefined ? 0 : val)
     this.next = (next===undefined  null : next)
  }
 

var deleteDuplicates = function(head) {
    
//const dummy = new ListNode(0, head);
const dummy = new ListNode;
dummy.next=head;
    let cur = dummy;
    while (cur.next && cur.next.next) {//curr节点,比较后两个数是否相等,
        if (cur.next.val === cur.next.next.val) {//如果这两个数相等
            const x = cur.next.val;//把相等的第一个数保存起来
            while (cur.next && cur.next.val === x) {//删除第一个数,循环下一个数是否等于x,如果等于,则删除,直到下一个数不为x
                cur.next = cur.next.next;
            } 
        } else {//不相等,则向下移动指针
            cur = cur.next;
        }
    }
    return dummy.next;
};

19. 删除链表中重复的数(多余的数)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yoxUO55O-1634807680157)(算法题练习.assets/image-20210618135158768.png)]

var deleteDuplicates = function(head) {
let curr=head;
if(!head){//不能写成head===[],否则会出错,可以写成head===null,或者!head
    return head;

}
else{
while(curr.next){
    if(curr.val===curr.next.val){
        curr.next=curr.next.next;
    }
    else{
        curr=curr.next;
    }
}}
return head;
};

20. 矩阵置零

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ySWyMYZX-1634807680157)(算法题练习.assets/image-20210618150844785.png)]

var setZeroes = function(matrix) {//不能创建新数组,只能在原数组中修改,把第一行和第一列用于记录是否更改为0的标志,但如果第一行或第一列本身就有0,则需要单独考虑
let isRow=false;

List item

let isCol=false;
for(let i=0;i

21.翻转链表1

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-reiPsq1R-1634807680157)(算法题练习.assets/image-20210830144822311.png)]

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var reverseList = function(head) {
let pre=null
let curr=head
while(curr){
    //先拿到第二个节点
    next=curr.next
    //再把当前节点指向前一个节点
    curr.next=pre
    //把前置节点修改为当前节点
    pre=curr
    //把当前节点修改为下一个节点
    curr=next 
}
return pre
};

21. 翻转链表2

思路:

  1. 将链表翻转

2.将翻转后的链表与原链表拼接

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NvFAxd0i-1634807680158)(算法题练习.assets/image-20210618161847911.png)]

var reverseBetween = function(head, left, right) {
    let curr=head;//curr指向头结点
let p1=null;//用于翻转链表
for(let i=1;i1){//翻转结束,如果不是从第一个头结点开始翻转,那么left-1所在在结点(p2),用p2连接right所在的节点p1;
    p2.next=p1;
    
}
else{//如果是从第一个节点开始翻转,那么新的链表的头结点一定是right所在的节点p1
    head=p1;
}
curr2.next=curr;//curr2是left所在的节点,应该连接到right+1的节点curr上
return head;
};

22. 买股票的最佳时机

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q3x2oTBs-1634807680158)(算法题练习.assets/image-20210618170926847.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fw7yxLyK-1634807680159)(算法题练习.assets/image-20210618171003339.png)]

var maxProfit = function(prices) {
    
let min=prices[0];
let max=0;
for(let i=0;imax){
            max=prices[i]-min;
        }
    }
}
return max;
};

22. 买股票的最佳时机2

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OEya2lVR-1634807680159)(算法题练习.assets/image-20210618213000827.png)]

var maxProfit = function(prices) {
let profit=0;
for(let i=0;i

23. 验证回文串

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R5OTc6uQ-1634807680159)(算法题练习.assets/image-20210620000337654.png)]

var isPalindrome = function(s) {
let s1=s.toLowerCase().replace(/[\W_]/g,"");//通过正在表达式按照在全局查找把全部字母变成小写字母并且把非字母替换为空
if(s.length<2){//一个字母肯定是回文串
    return true;
}
let left=0;
let right=s1.length-1;
while(left

24. 环形链表

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6RVDI1X9-1634807680160)(算法题练习.assets/image-20210620154457902.png)]

 function ListNode(val) {
      this.val = val;
      this.next = null;
 }
var hasCycle = function(head) {
    let lost=head;//定义两个指针,一个慢指针,一个快指针
    let fast=head;
    if(!head){
        return false;
    }
    while(fast.next!=null&&fast.next.next!=null){//不能是lost.next,当fast后面没有节点,还有后面只有一个节点是停止,
        lost=lost.next;//慢指针一次走一步
        fast=fast.next.next;//快指针一次走两步
        while(lost===fast){//如果某一时刻相遇,则该链表有环
            return true;
        }
    }
    return false;
};

25. 寻找旋转排序数组中的最小值

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nukgqWeo-1634807680160)(算法题练习.assets/image-20210621140133363.png)]

var findMin = function(nums) {
if(nums.length<2){
    return nums;
}
let left=0;
let right=nums.length-1;
if(nums[left]nums[mid+1]){//如果中间值为前半部分的最大值,那么下一位则为最小值
        return nums[mid+1];
    }
    if(nums[mid-1]>nums[mid]){//如果中间值为后半部分的最小值
        return nums[mid];
    }
    if(nums[left]nums[mid]){//同理,砍掉后半部分,前半部分继续二分
        right=mid-1;
    }
}
};

26. 相交链表

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k3JdnNhz-1634807680162)(算法题练习.assets/image-20210623001433837.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rmf7UN7g-1634807680162)(算法题练习.assets/image-20210623000940098.png)]

思路:a+b+c=d+e+f;如果他们相交,则他们在走过这三段路之后必相遇。单向链表。

var getIntersectionNode = function(headA, headB) {
    let n1=headA;
    let n2=headB;
    while(n1!==n2){//包含两个不相交的链表,A链表走完之后,指针移到链表B的头结点开始走,当n1=n2相等时,也就是n1,n2都走到链表末尾,都为null,符合题目要求。
        if(n1===null){//A链表走完之后,指针移到链表B的头结点开始走,直到n1=n2,他们相遇
            n1=headB;
        }else{
           n1=n1.next;
        }
        if(n2===null){//这里不能只是一个'=',条件判断至少要两个‘=’,一个‘=’是赋值
            n2=headA
        }
        else{
            n2=n2.next
        }
    }
    return n1;
    // var getIntersectionNode = function(headA, headB) {
    // if (headA === null || headB === null) {
    //     return null;
    // }
    // let pA = headA, pB = headB;
    // while (pA !== pB) {
    //可写成三元表达式
    //     pA = pA === null ? headB : pA.next;
    //     pB = pB === null ? headA : pB.next;
    // }
    // return pA;
};

27. 重复的DNA序列

编写一个函数来找出所有目标子串,目标子串的长度为 10,且在 DNA 字符串 s 中出现次数超过一次

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0WODcihc-1634807680163)(算法题练习.assets/image-20210624001617217.png)]

var findRepeatedDnaSequences = function(s) {
    let map=new Map();
    let result=[];
    let i=0;
// for(let i=0;i+10<=s.length;i++){
//     const dna=s.substring(i,i+10);

// if(map.get(dna)===undefined){
//     map.set(dna,1);
// }
// else if(map.get(dna)===1){
//     map.set(dna,2);
//     result.push(dna);
// }
// else{
//     map.set(dna,map.get(dna)+1)
// }
// }

while(i+10<=s.length){
        const dna=s.substring(i,i+10);//这里是i+10,而不是10,每次去十位字符串,起点是i,终点是i+10.
if(map.get(dna)===undefined){//这是是get方法,获取这个字符串的key值,如果不存在,则添加到map中去
    map.set(dna,1);
}
else if(map.get(dna)===1){//如果该字符串之前已经有了,那么则把key值标为2,并添加到结果中去
    map.set(dna,2);
    result.push(dna);
}
else{//之后的字符串超过两次出现,则修改出现的次数+1
    map.set(dna,map.get(dna)+1)
}
i++;
}
return result
};

28.打家劫舍

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2C2IhKTm-1634807680163)(算法题练习.assets/image-20210625002243581.png)]

/**
 * @param {number[]} nums
 * @return {number}
 */
var rob = function(nums) {
    if(nums.length<2){
        return nums[0]
    }
    if(nums.length===2){
        return Math.max(nums[0],nums[1])
    }
let meno=[];//用meno来记录每个位置能偷的最大值
meno[0]=nums[0];
meno[1]=Math.max(meno[0],nums[1]);
for(let i=2;i

29. 存在重复元素

var containsDuplicate = function(nums) {
let set=new Set();
for(let i=0;i<nums.length;i++){
    if(set.has(nums[i])){
        return true
    }
    else{
        set.add(nums[i])
    }
}
return false;
};

30.存在重复元素2

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ggVyf3Rf-1634807680164)(算法题练习.assets/image-20210808002357258.png)]

var containsNearbyDuplicate = function(nums, k) {
let map=new Map();
for(let i=0;i<nums.length;i++){
    if(map.has(nums[i])&&(i-map.get(nums[i])<=k)){//如果该元素与map中的元素相等,则证明已经存在,如果该元素的下标值与map中的key值的差小于等于k,则符合题目要求。
        return true
    }
    else{
        map.set(nums[i],i)//把不存在的值和下标值都加入到map中
    }
}
return false;
};

31. 有效的字母异位词

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RCw3gf2B-1634807680164)(算法题练习.assets/image-20210626133022914.png)]

var isAnagram = function(s, t) {
let map=new Map();
if(s.length!==t.length){
    return false;
}
for(let i=0;i

32. 移动零

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3UF8eqkU-1634807680180)(算法题练习.assets/image-20210808001900581.png)]

var moveZeroes = function(nums) {
let j=0;
// 遍历数组,把数组中不为0的元素依次移动到最前面,并且记录不为0元素的个数j,j之后的元素全部设为0
for(let i=0;i

33. 奇偶链表

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7nrY1iMg-1634807680180)(算法题练习.assets/image-20210629002320737.png)]

var oddEvenList = function(head) {
    if(!head){
        return null
    }
    if(head.next===null){
        return head;
    }
    // 奇数节点
let odd=head;
// 偶数节点
let even=head.next;
// 标记第一个偶数节点,用于把最后的奇数节点与其连接组成新链表
let tagEven=head.next;
while(even&&even.next){
    //循环条件,当偶数节点存在和偶数节点的下一个节点存在时,奇数节点指针指向下一个奇数节点,偶数节点指针指向下一个偶数节点。
    odd.next=odd.next.next;
    odd=odd.next;
    even.next=even.next.next;
    even=even.next;
}
odd.next=tagEven;
return head;
};

34. 两个数组的交集

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YxzxqwRT-1634807680181)(算法题练习.assets/image-20210701005321400.png)]

var intersection = function(nums1, nums2) {
let result=new Set()
let set=new Set(nums2)
for( num of nums1){
    if(set.has(num)){
        result.add(num)
    }
}
return Array.from(result);
};

35. 验证回文串2

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gpgKZ7W6-1634807680181)(算法题练习.assets/image-20210702002609097.png)]

/**
 * @param {string} s
 * @return {boolean}
 */
var validPalindrome = function(s) {
    // 这是判断是否是回文串的函数
function valid(left,right){
    while(left

36. 甲板上的战舰

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZbZgaKOZ-1634807680182)(算法题练习.assets/image-20210702002937888.png)]

/**
 * @param {character[][]} board
 * @return {number}
 */
var countBattleships = function(board) {
let result=[]
// 根据题目的意思,如果某元素为X,则把他周围的都表示为.,利用递归的思想,则会把X所有相邻的元素变为.题目中不会出现无效样例
for(let row=0;row=board[0].length||row>=board.length||col<0||board[row][col]==="."){
    return;
    
}
board[row][col]="."
dfs(row-1,col)
dfs(row,col-1)
dfs(row,col+1)
dfs(row+1,col)
}
return result
};

37. 矩阵重叠

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CSAoLnPd-1634807680182)(算法题练习.assets/image-20210702235640097.png)]

/**
 * @param {number[]} rec1
 * @param {number[]} rec2
 * @return {boolean}
 */
var isRectangleOverlap = function(rec1, rec2) {
    // 如果一个矩阵在另一个矩阵的四周,则不重叠,返回false
if(rec1[2]<=rec2[0]||rec1[3]<=rec2[1]||rec1[1]>=rec2[3]||rec1[0]>=rec2[2]){
    return false
}
else return true
};

38. 旋转字符串

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xpFAjQLq-1634807680183)(算法题练习.assets/image-20210703000029095.png)]

var rotateString = function(s, goal) {
    if(s.length!==goal.length){
        return false
    }
    // 在某位加入原字符串组成新的字符串,经过旋转的新的字符串一定包含在内
const a=s+s;
if(a.includes(goal))
return true
else
return false
};

39.图像渲染

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FfV27hsg-1634807680183)(算法题练习.assets/image-20210703001433617.png)]

var floodFill = function(image, sr, sc, newColor) {
    if(image[sr][sc]===newColor){
        return image
    }
const oldColor=image[sr][sc]
// 记录坐标的颜色
function dfs(sr,sc){
    // 如果越界,或者不等于原坐标颜色,则直接return
    if(sr<0||sr>=image.length||sc<0||sc>=image[0].length||image[sr][sc]!==oldColor){
        return
    }
    // 如果该位置的元素等于原坐标颜色,则将该位置染上新颜色,继续向四周递归遍历,如果四周的元素的颜色跟oldColor颜色相等,则需要染上新颜色
    image[sr][sc]=newColor
    dfs(sr-1,sc)
    dfs(sr+1,sc)
    dfs(sr,sc-1)
    dfs(sr,sc+1)
}
dfs(sr,sc)
return image
};

40. 岛屿的最大面积

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dGrkYLP7-1634807680183)(算法题练习.assets/image-20210703005458946.png)]

/**
 * @param {number[][]} grid
 * @return {number}
 */
var maxAreaOfIsland = function(grid) {
   
    let s=0
function dfs(i,j){
    // 搜索算法,遇到1,则沉没该岛
    if(i<0||i>=grid.length||j<0||j>=grid[0].length||grid[i][j]===0){

        return 0}
        // 一定要沉没该岛屿,不然下一个递归的时候会搜索到该岛屿
        grid[i][j]=0
        // 这下面是递归的重点,每一次结果都与后面的递归结果有关,递归结束后,结果就出来了
let count=1
count+=dfs(i-1,j)
count+=dfs(i+1,j)
count+=dfs(i,j-1)
count+=dfs(i,j+1)
return count;
}
for(let i=0;i

41. 链表中的中间节点

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CsrY7kiL-1634807680183)(算法题练习.assets/image-20210704211952173.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7l8UUTGW-1634807680185)(算法题练习.assets/image-20210704212006178.png)]

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var middleNode = function(head) {
let slow=head;
let fast=head;
// 定义两个快慢指针,初始指向头结点,当快指针指向最后节点时并且快指针不存在时循环结束
while(fast!==null&&fast.next!==null)
{fast=fast.next.next;
    slow=slow.next;
}
// 结束循环之后,慢指针slow指向的就是中间的节点,返回结果为slow为头结点的链表
return slow
};

42.按奇偶排序数组

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UEhLxcjS-1634807680185)(算法题练习.assets/image-20210704214717720.png)]

/**
 * @param {number[]} nums
 * @return {number[]}
 */
var sortArrayByParity = function(nums) {
let i=0
let j=nums.length-1
// 定义两个指针,一个指向首元素,一个指向末尾元素,在四种条件下执行相应的操作交换元素,就可以达到目的
while(i

43. 按奇偶排序是数组2

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0q5uC4fA-1634807680185)(算法题练习.assets/image-20210704221346065.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4K74Yrd7-1634807680185)(算法题练习.assets/image-20210704221359427.png)]

/**
 * @param {number[]} nums
 * @return {number[]}
 */
var sortArrayByParityII = function(nums) {
    // 算法思想:下标值为偶数时,则该数也为偶数,下标值为奇数时,则该数也为奇数,通过i指针表示偶数指针,通过j来表示奇数指针,当偶数指针所在的元素不为偶数时,则需要把原数组中下标为奇数的偶数与其交换
    let j=1
for(let i=0;i

44.字符串算术运算

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bNvbDnVH-1634807680186)(算法题练习.assets/image-20210731163819051.png)]

// 思路:找到[在字符串中的index,然后找到重复次数index-2,和重复字符串,因为重复次数和重复字符串不只是一位数,所以需要两个while循环找到正确的重复次数和重复字符串,找到第一个需要重复的字符串,通过for循环,用res记录每一次循环的结果,通过字符串拼接的方法,用target记录上一次处理完之后的字符串,i=0时,res=item+target acc,之后把第一次拼接好的字符串加到第二次拼接的字符串上accacc,以此类推得到结果
function x(str) {
  let target = ''
  let res = ''
  // 循环条件是字符串中有最后一个[字符串
  while (str.lastIndexOf("[") > 0) {
    let index = str.lastIndexOf("[")
    let numIndex = index - 2
    let letterIndex = index + 1
    let num = ''
    let item = ''
    while (numIndex >= 0) {
      if (!/[0-9]/.test(str[numIndex])) break
      num = str[numIndex] + num
      numIndex--
    }
    while (letterIndex < str.length) {
      if (!/[a-zA-Z]/.test(str[letterIndex])) break
      item = item + str[letterIndex]
      letterIndex++
    }

    for (let i = 0; i < num; i++) {
      if (i === 0) {
        res = item + target

      }
      else {
        res = item + target + res
      }
    }

    target = res

    str = str.slice(0, index)
  }
  return res
}
let a = "3*[a2*[c]]"
console.log(x(a));

45.手写instanceOf

// 手写instance of 
// left是实例对象,right是构造函数,原理是通过原型链实现
function instanceOf(left, right) {
  if (typeof left !== "object" && typeof left !== "function" || typeof left === null) {
    return false
  }
  if (typeof right !== "function" && typeof right !== "object" || typeof right === null) {
    return false
  }
  // 找到实例对象的原型
  let proto = left.__proto__
  // 找到构造函数的原型
  let protoType = right.prototype
  while (true) {
    // 当找到null的时候,已经到了原型链顶端
    if (proto === null) {
      return false
    }
    // 如果两个原型相等,则返回true
    if (proto === protoType) {
      return true
    }
    // 否则,继续网原型链上找
    proto = proto.__proto__
  }
}
let a = [1, 2, 3]
console.log(instanceOf(a, Object));
let b = a instanceof Object
console.log(b);
true
true

46.冒泡排序

function x(nums) {
  let temp
  for (let i = 0; i < nums.length; i++) {
    for (let j = 0; j < nums.length - i; j++) {
      if (nums[j] > nums[j + 1]) {
        temp = nums[j + 1]
        nums[j + 1] = nums[j]
        nums[j] = temp
      }
    }
  }
  return nums
}
let a = [6, 5, 4, 3, 2, 1]
console.log(x(a));

47.最大正方形

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WVU6EW4L-1634807680187)(算法题练习.assets/image-20210807175930701.png)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-thVk68NA-1634807680187)(算法题练习.assets/image-20210807175949644.png)]

// 最大正方形
function maxSquare(matrix) {
  // 构造一个dp数值,记录每个坐标存在的最大的正方形
  const dp = new Array(matrix.length).fill(0)
  let maxSize = 0
  for (let i = 0; i < matrix.length; i++) {
    dp[i] = new Array(matrix[0].length).fill(0)
    let a = matrix[0].length
    for (let j = 0; j < a; j++) {
如果该元素是1,则需要做改变,是0,则不用
      if (matrix[i][j] === 1) {
        // 如果原数组第一行和第一列的元素等于1,则直接该数组的该位置等于1
        if (i === 0 || j === 0) {

          dp[i][j] = 1
        }
        // 否则,则取左方元素,上方元素,左上方元素的最小值+1,就是该位置的元素
        else {
          dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]) + 1
        }
      }
      // 最大的面积
      maxSize = Math.max(maxSize, dp[i][j])
    }
  }
  console.log(dp);
  return maxSize * maxSize

}
let a = [[1, 1, 1], [1, 1, 1], [1, 1, 1]]

console.log(maxSquare(a));
[ [ 1, 1, 1 ], [ 1, 2, 2 ], [ 1, 2, 3 ] ]
9

48.JS实现输出一个字符串中第一个连续递增的三个数字

function num(str) {
  let result = []
  for (let i = 0; i < str.length; i++) {
    let a = str[i] - "0"
    // console.log(a);
    let b = str[i + 1] - "0"
    let c = str[i + 2] - "0"
    if (c > b && b > a) {
      console.log(a, b, c);
      result.push(str[i], str[i + 1], str[i + 2])
      return result.join("")
    }
  }
  return result
}
let x = "122345"
let y = num(x)
console.log(y);
2 3 4
234

49.输出数组中每个元素比它小的元素的个数

输入[8,1,2,2,3]

输出[4,0,1,1,3]

function x(nums) {
  let map = new Map()
  let result = []
  for (let i = 0; i < nums.length; i++) {

    // set.add(nums[i])
    let count = 0
    for (let j = 0; j < nums.length; j++) {

      if (nums[j] < nums[i]) {

        count++

      }
    } map.set(i, count)
  }
  console.log(map);
  // 这里不能用for in 
  for (let str of map) {
    console.log(str);
    result.push(str[1])
  }
  return result
}
let a = [8, 1, 2, 2, 3]
console.log(x(a));
-------------------------
Map(5) { 0 => 4, 1 => 0, 2 => 1, 3 => 1, 4 => 3 }
[ 0, 4 ]
[ 1, 0 ]
[ 2, 1 ]
[ 3, 1 ]
[ 4, 3 ]
[ 4, 0, 1, 1, 3 ]

// 获取对象的键名key

// 获取对象的键名key和键值values 
let obj = { a: 1, b: 2, c: 3 }
for (let key in obj) {
  console.log(key);
}
let objKey = Object.keys(obj)
let objValue = Object.values(obj)
console.log(objKey);
console.log(objValue);
---------------
a
b
c
[ 'a', 'b', 'c' ]
[ 1, 2, 3 ]
// 当我们使用Number作为对象的key时,根据key以数字顺序返回的值
var an_obj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.values(an_obj)); // ['b', 'c', 'a']

添加字符串倒序输出字符串的方法

// 添加字符串倒序输出字符串的方法
let a = "12345"
// 字符串转数组的方式
let b = a.split("")
console.log(b);
console.log(b.reverse().join(""));
String.prototype.Myreverse = function () {
  for (let i = this.length - 1; i >= 0; i--) {

    console.log(this[i]);
  }
}
a.Myreverse()
[ '1', '2', '3', '4', '5' ]
54321
5
4
3
2
1

50.快速排序

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-euo2inTU-1634807680187)(算法题练习.assets/image-20210812161241917.png)]

快速排序在什么情况下最不利于发挥其有点:
快速排序的一次划分算法从两头交替搜索,直到low和high重合,因此其时间复杂度是O(n);而整个快速排序算法的时间复杂度与划分的趟数有关。

理想的情况是,每次划分所选择的中间数恰好将当前序列几乎等分,经过log2n趟划分,便可得到长度为1的子表。这样,整个算法的时间复杂度为O(nlog2n)。

最坏的情况是,每次所选的中间数是当前序列中的最大或最小元素,这使得每次划分所得的子表中一个为空表,另一子表的长度为原表的长度-1。这样,长度为n的数据表的快速排序需要经过n趟划分,使得整个排序算法的时间复杂度为O(n2)。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-I9RWzsW6-1634807680188)(算法题练习.assets/6524741_1489243629314_792B9001DFB7D6F2C5286D786EDED619)]

function quickSort(array) {
  let sort = function (array, left = 0, right = array.length - 1) {
    // 结束条件,以为下面有两个递归调用函数,如果没有结束条件,那么将一直执行下去。说明整理完毕
    if (left >= right) {
      return
    }

    let i = left
    let j = right
    // 取无序数组中的第一个元素作为中枢值
    let baseValue = array[i]
    // 把所有比中枢值小的放左边,比中枢值大的放右边
    while (i < j) {
      // 从右边开始找到比中枢值小的放到左边
      while (i < j && array[j] >= baseValue) {
        j--
      }
      array[i] = array[j]
      // 从左边找到比中枢值大的放到右边
      while (i < j && array[i] < baseValue) {
        i++
      }
      array[j] = array[i]
    }
    // 此时的i所在的位置是空的,把中枢值放在该位置
    array[i] = baseValue
    sort(array, left, i - 1)
    sort(array, i + 1, right)
  }
  //  为了保证这个函数是纯函数拷贝一次数组
  // let newArr = array.concat()
  sort(array)
  return array
}
let b = [2, 1, 4, 2, 5, 3, 9]
let c = quickSort(b)
console.log(c);
-----------
    [
  1, 2, 2, 3,
  4, 5, 9
]
参考
function quick(arr){
    if(arr.length<=1){
        return arr;
    }
    var left = [],
        right = [],
        k = arr.splice(0, 1)[0];
        for(var i = 0;ik){
                right.push(arr[i]);
            }else{
                left.push(arr[i]);
            }
        }
        return quick(left).concat([k],quick(right));
}

51.手写split实现字符串用;;分割[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eIq65Lmy-1634807680188)(算法题练习.assets/image-20210812162200174.png)]

let a = ";aa;;bb;;;ccc;;;;d;;"
function x(str) {
  let result = []
  // 循环条件是字符串中存在;;
  while (str.indexOf(";;") !== -1) {
    // 用来记录;;的下标值
    let t
    // 用来保存需要添加的字符串
    let a = ""
    let index = str.indexOf(";;") - 1
    t = index
    while (index >= 0) {
      a = str[index] + a
      index--
    }
    // for (let i = 0; i < str.length; i++) {
    //   // 当字符串中存在;;
    //   if (str[i] === ";" && str[i + 1] === ";") {
    //     // 这是需要添加的字符串的末尾位置
    //     let index = i - 1

    //     t = i
    //     console.log(i);
    //     break
    //   }
    // }
    // 把a添加进数组
    result.push(a)
    console.log(a);
    // 重新取字符串
    str = str.substring(t + 3)
    if (str === "") {
      result.push("")
      return result
    }
    if (str.indexOf(";;") === -1) {
      result.push(str)
      return result
    }
    console.log(str);
  }
  return result
}
let b = x(a)
console.log(b);
let c = a.indexOf(";;")
console.log(c);
-----------------
    ;aa
bb;;;ccc;;;;d;;
bb
;ccc;;;;d;;
;ccc
;;d;;

d;;
d
[ ';aa', 'bb', ';ccc', '', 'd', '' ]
3

52.第一个错误的版本

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fzro9oJS-1634807680189)(算法题练习.assets/image-20210812171916684.png)]

var solution = function(isBadVersion) {
    /**
     * @param {integer} n Total versions
     * @return {integer} The first bad version
     */
    return function(n) {
        let left=1,right=n
        while(left

53.字符串相加

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4CvGk6On-1634807680190)(算法题练习.assets/image-20210812174357543.png)]

var addStrings = function (num1, num2) {
  let i = num1.length - 1
  let j = num2.length - 1
  let add = 0
  let result = []
//   这里重要的是这个循环条件,当i=0,j=0的时候是两个字符串最开始的字符,只要有一个没计算完成,都要继续循环下去,把已经计算完的字符用0表示,当只有1+9的时候,要进位等于10,则循环条件要加上add!==0这个条件,
  while (i >= 0 || j >= 0||add!==0) {
    let x =i>=0? num1.charAt(i) - "0":0
    let y =j>=0? num2.charAt(j) - "0":0
    let sum = x + y + add
    result.unshift(sum % 10)
    add = Math.floor(sum / 10)
    i--
    j--
  }
  return result.join("")
}
------------
// 字符串两数之和
function addTwos(num1, num2) {
  let i = num1.length - 1, j = num2.length - 1
  let add = 0
  let sum
  let result = ""
  while (i >= 0 || j >= 0 || add != 0) {
    let x = num1[i] >= 0 ? num1[i] - "0" : 0
    let y = num2[j] >= 0 ? num2[j] - "0" : 0
    sum = x + y + add
    result = sum % 10 + result
    add = Math.floor(sum / 10)
    i--
    j--
  }
  return result
}

console.log(addTwos("120", "945"));
let a = "123", b = "934"
console.log((a - "0") + (b - "0"));

54.判断子序列

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bddQInJH-1634807680190)(算法题练习.assets/image-20210821021345814.png)]

var isSubsequence = function(s, t) {
let m=s.length,n=t.length
let i=0,j=0
while(i

55.字符串中重复出现最多的字符

function x(str) {
  let map = new Map()
  let maxLength = 0
  let s = ""
  for (let i = 0; i < str.length; i++) {
    if (!map.has(str[i])) {
      map.set(str[i], 1)
    }
    else {
      map.set(str[i], map.get(str[i]) + 1)
    }
    if (maxLength < map.get(str[i])) {
      maxLength = map.get(str[i])
      s = str[i]
    }
  }
  return s
}

console.log(x(a));

56.数组变换

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XxH88eeY-1634807680190)(算法题练习.assets/image-20210826185308548.png)]

var num=parseInt(readline()) 

let str
let line
while(line = readline()){ // readline 得到的是字符串
    let p = line.split(' ');
    let a = parseInt(p[0]); // 单行第一个参数 转化成了数字
    let b = parseInt(p[1]); // 单行第二个参数 转化成了数字
    str=p
    //print(p);
}

function x(s){
   for(let i=0;i

57.连续字符

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Wl793f5g-1634807680190)(算法题练习.assets/image-20210827171128723.png)]

var maxPower = function(s) {
 
  let ss = /(\w)\1*/g
let b = s.match(ss).sort((a, b) => b.length - a.length)[0].length
return b
};

58.最长连续子字符串

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RcwxMNTr-1634807680191)(算法题练习.assets/image-20210827220012119.png)]

function findLongestSubstr( str ) {
    // write code here
  let s1=str.toLowerCase()
   let ss = /(\w|\s)\1*/g
  let b = s1.match(ss).sort((a, b) => b.length - a.length)[0]
  for(let i=0;i

59.找出只出现一次的字符

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4u81tzIL-1634807680192)(算法题练习.assets/image-20210827220752172.png)]

function lastUniqueChar(str) {
  // write code here
    if(str.length-1<1){
        return str
    }
  let map = new Map()
  for (let i = 0; i <= str.length; i++) {
    if (!map.has(str[i])) {
      map.set(str[i], 1)
    }
    else {
      map.set(str[i], map.get(str[i]) + 1)
    }
  }
  for (let i = str.length - 1; i >= 0; i--) {
 
    if (map.get(str[i]) === 1) {
      // console.log(str[i]);
      return str[i]
    }
  }
    return ""
}

60.关于树

https://leetcode-cn.com/problems/binary-tree-preorder-traversal/solution/die-dai-chao-jian-dan-er-cha-shu-qian-zh-z1k5/

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0IryLDfm-1634807680192)(算法题练习.assets/image-20210827230510579.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OtiQ13QT-1634807680193)(算法题练习.assets/image-20210827230450947.png)]

1前序遍历

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var preorderTraversal = function(root) {
let res=[]
let stack=[]
while(root||stack.length){
    // 当该节点的左子节点不存在时跳出循环,把所有的左子节点加入到栈中,到最后一个左子节点,然后出栈,遍历栈中元素的右节点,如果有右节点则继续遍历
    while(root){
        res.push(root.val);
        stack.push(root);
        root=root.left
    }
    root=stack.pop()
    root=root.right
}
return res
};

2.中序遍历

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var inorderTraversal = function(root) {
let res=[]
let stack=[]
while(root||stack.length){//循环条件是该节点不为空和栈中元素不为空
    // 把所有的左子节点加入到栈中,最后一个进栈的就是最左节点
    while(root){
       stack.push(root)
        root=root.left 
            
    }
    // 把栈中最后一个元素推送出来,加入到res中,再看该元素是否有右子树
    root=stack.pop();
res.push(root.val)
root=root.right

}
return res
};

3.后序遍历

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var postorderTraversal = function(root) {
let res=[]
let stack=[]
while(root||stack.length){
    while(root){
        stack.push(root)
        res.unshift(root.val)
        root=root.right
    }
    root=stack.pop()
    root=root.left
}
return res
};

4.二叉树的最大深度

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number}
 */
var maxDepth = function(root) {
if(!root){
    return 0
}
else{
    return 1 + Math.max(maxDepth(root.left),maxDepth(root.right))
}
}

5.二叉树的层次遍历

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5AyypYMW-1634807680193)(算法题练习.assets/image-20210828205554291.png)]

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number[][]}
 */
var levelOrder = function(root) {
let res=[]
let queue=[]
queue.push(root)
if(!root){//写成root===null也可以
    return res
}
// 当队列的长度为0时结束循环
while(queue.length!==0){
    // 记录每一次循环的队列的长度
    let length=queue.length
    // 用来保存每一层的节点数据
    let currntVal=[]
    // 遍历每一层的节点
    for(let i=0;i

6.二叉树的右视图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-T6X4oV4T-1634807680193)(算法题练习.assets/image-20210828213506922.png)]

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var rightSideView = function(root) {
let res=[],queue=[]
queue.push(root)
if(!root){
    return res
}
// 把每一层的最后一个节点存储到res中
while(queue.length!==0){
    // 记录当前层级节点个数
    let length=queue.length
    // 这里必须还要有一个循环遍历,当遍历到最后一个元素的时候才把该元素的值添加到数组中,
    // 不然就找不到每一层的最后一个元素,因为每次都会添加到新元素进来,队列的长度会变,只能找到最后一层的最后一个元素
    // 以当前层级的节点数为遍历条件
   while(length--) {
       let node=queue.shift()
if(length===0){
    res.push(node.val)
}
node.left&&queue.push(node.left)
   node.right&&queue.push(node.right)
}
// 也可以改写为一下代码,用for循环代替while循环
// 注意:由于for循环里面会改变length的大小,所有会导致每次循环的length改变,所以需要将每一层队列的长度先保存起来
// let l=length
// for(let i=0;i

7.平衡二叉树

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2pCQlS4y-1634807680194)(算法题练习.assets/image-20210829232159159.png)]

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {boolean}
 */
var isBalanced = function(root) {
    // 下面是一个求一棵树的最大深度的函数
function depth(root){
    if(!root){
        return 0
    }
    else{
        return 1+Math.max(depth(root.left),depth(root.right))
    }
}
if(!root){
    return true
}
else{
    // 求到根节点的左子节点的深度
   let l= depth(root.left)
//    求到根节点的右子节点的深度
   let r=depth(root.right)
//    这里不但判断根节点的左右子节点的深度是否满足平衡二叉树,还需要判断每一个节点是否满足二叉树,所以需要递归调用,当每一个节点和它的左右子节点多满足时,这棵树才是平衡二叉树。
   return Math.abs(r-l)<=1&&isBalanced(root.left)&&isBalanced(root.right)
}
};

8.二叉树的直径

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9a8QSKJI-1634807680194)(算法题练习.assets/image-20210829234513993.png)]

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number}
 */
var diameterOfBinaryTree = function(root) {
    // 下面是求一棵树的最大深度的函数
function depth(root){
    if(!root){
        return 0
    }
    else{
        return 1+Math.max(depth(root.left),depth(root.right))
    }
}
// 如果节点为空,则返回0 把该节点的最大路径置为0
if(!root){
    let res=0
    return 0
}
else{
    // 取得根节点的左子节点的最大深度
  let l=  depth(root.left)
//   取得根节点的右节点的最大深度
  let r=  depth(root.right)
//   res作为该节点存在的最大路径
   res=l+r
//    这里也需要递归调用本函数,取得该节点和它的左右子节点的最大路径的最大值作为结果
  return Math.max(res,Math.max(diameterOfBinaryTree(root.left),diameterOfBinaryTree(root.right)))
}
};

9.路径总和

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oefsywKh-1634807680195)(算法题练习.assets/image-20210830000748959-1630253271190.png)]

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @param {number} targetSum
 * @return {boolean}
 */
var hasPathSum = function(root, targetSum) {
    // 注意该题目是根节点到叶子节点,如果存在该路径,则必须满足一下的条件
if(!root){
    return false
}
// 当该节点的值和目标值相等并且它没有左右子节点,那满足题目条件
if(!root.left&&!root.right&&root.val===targetSum){
    return true
}
// 继续递归,把该节点的左右子节点作为第一个参数,把目标值与它的差作为第二个参数,一直遍历到叶子结点就可以知道结果了

else{
    return hasPathSum(root.left,targetSum-root.val)||hasPathSum(root.right,targetSum-root.val)
}
};

10.对称二叉树

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Acgxp4Or-1634807680195)(算法题练习.assets/image-20210830003936076.png)]

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {boolean}
 */
//  重点是:确定终止条件
// 要比较两个节点数值相不相同,首先要把两个节点为空的情况弄清楚!否则后面比较数值的时候就会操作空指针了。

// 节点为空的情况有:(注意我们比较的其实不是左孩子和右孩子,所以如下我称之为左节点右节点)

// 左节点为空,右节点不为空,不对称,return false
// 左不为空,右为空,不对称 return false
// 左右都为空,对称,返回true
// 此时已经排除掉了节点为空的情况,那么剩下的就是左右节点不为空:

// 左右都不为空,比较节点数值,不相同就return false
// 此时左右节点不为空,且数值也不相同的情况我们也处理了。

var isSymmetric = function(root) {
    // 注意:这里是镜像对称,也就是说当有一个节点只有左右节点其中一个,那就不符合题目要求
    // 这里对称需要两个同样的树进行对比,一树的左子节点跟二树的右子节点对比,同理一树的右子节点跟二树的左子节点对比
function check(leftNode,rightNode){
    // 刚开始是根节点进行对比,因为只有一个根节点的树肯定是对称的
    // 通过递归比较最后的叶子结点都能够一起存在,则返回true
    if(!leftNode&&!rightNode){
        return true
    }
    if(!leftNode||!rightNode){
        return false
    }
    return (leftNode.val===rightNode.val)&&check(leftNode.left,rightNode.right)&&check(leftNode.right,rightNode.left)
}
return check(root,root)
};

11.翻转二叉树

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KtIU5mSJ-1634807680195)(算法题练习.assets/image-20210830114003903.png)]

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {TreeNode}
 */
var invertTree = function(root) {
    // 如果根节点为空,则返回null
    if(!root){
        return null
    }
    // 两两交换左右子节点
[root.left,root.right]=[root.right,root.left];
// 递归调用该函数,
invertTree(root.left)
invertTree(root.right)
return root
};

12.二叉搜索树的第K大的节点

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-irzoVjuV-1634807680195)(算法题练习.assets/image-20210830123134945.png)]

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} root
 * @param {number} k
 * @return {number}
 */
var kthLargest = function(root, k) {
    // 通过中序遍历,结果是一个升序数组,然后通过翻转数组即可
let res=[]
// 这里应该用栈,先进后出,而不是队列,队列是先进先出
let stack=[]
while(root||stack.length){
    while(root){
        stack.push(root)
        root=root.left
    }
    root=stack.pop()
    res.push(root.val)
    root=root.right
}
let ress=res.reverse()
return ress[k-1]
};

13.二叉树遍历的优化

1.后序遍历

var postorderTraversal = function(root) {
let res=[]
function dfs(root){
    if(!root){
        return;
    }
    dfs(root.left)
    dfs(root.right) 
    res.push(root.val)
}
dfs(root)
return res

};

2.中序遍历

var inorderTraversal = function(root) {
let res=[]
function dfs(root){
    if(!root){
        return
    }
    dfs(root.left)
      res.push(root.val)
    dfs(root.right)
}
dfs(root)
return res
};

3.前序遍历

var preorderTraversal = function(root) {
let res=[]
function dfs(root){
    if(!root){
        return
    }
    res.push(root.val)
    dfs(root.left)
    dfs(root.right)
}
dfs(root)
return res
};

14.另一颗树的子树

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zuJ0zCJd-1634807680196)(算法题练习.assets/image-20210830142741829.png)]

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @param {TreeNode} subRoot
 * @return {boolean}
 */
var isSubtree = function(root, subRoot) {
    // 这是一个比较两棵树是否相同的函数
 function isSametree(s,t){
     if(!s&&!t){
         return true
     }
    if(s&&t&&s.val===t.val &&isSametree(t.left,s.left)&&isSametree(t.right,s.right)){
         return true
     }
     return false
 }
 if(!root){
     return false
 }
//  如果比较根节点相同,则他们是相同的树
 if(isSametree(root,subRoot)){
     return true
 }
//  如果不相同,则比较第一颗树的左右子树与第二棵树是否是同一颗树
 return isSubtree(root.left,subRoot)||isSubtree(root.right,subRoot)
};
// 判断两个树是否相同
// const isSameTree = (p, q) => {
//     if (!p && !q) return true;
//     if (p && q && p.val === q.val && isSameTree(q.left, p.left) && isSameTree(q.right, p.right)) {
//         return true;
//     }
//     return false;
// };

// const isSubtree = (s, t) => {
//     // 递归出口
//     if (!s) return false;
//     // 若两个树相同,肯定是true
//     if (isSameTree(s, t)) return true;
//     // 不相同,就递归判断s的左右子树
//     return isSubtree(s.left, t) || isSubtree(s.right, t);
// };


14.相同的树

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-02vgIwT7-1634807680197)(算法题练习.assets/image-20210830143301289.png)]

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} p
 * @param {TreeNode} q
 * @return {boolean}
 */
var isSameTree = function(p, q) {
if(!p&&!q){
    return true
}
// 或者
// if(p&&q&&p.val===q.val&&isSameTree(p.left,q.left)&&isSameTree(p.right,q.right)){
//     return true
// }
// return false

if(!p||!q){
    return false
}
return p.val===q.val&&isSameTree(p.left,q.left)&&isSameTree(p.right,q.right)
};

61.x的平方根

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kQBkqGkZ-1634807680197)(算法题练习.assets/image-20210830151211067.png)]

/**
 * @param {number} x
 * @return {number}
 */
var mySqrt = function(x) {
    if(x<2){
        return x
    }
let left=1,mid,right=Math.floor(x/2)
while(left<=right){
     mid=Math.floor((left+right)/2)
 
    if(mid*mid===x){return mid}
    // 注意这里不是right++,left--,它的位置跟mid有关
    if(mid*mid>x){
        right=mid-1
    }
    else{
        left=mid+1
    }
   
}
return right
};


62.用栈实现队列

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GYu3jHD2-1634807680198)(算法题练习.assets/image-20210830153007486.png)]

/**
 * Initialize your data structure here.
 */
var MyQueue = function() {
this.queue=[]
};

/**
 * Push element x to the back of this.queue. 
 * @param {number} x
 * @return {void}
 */
MyQueue.prototype.push = function(x) {
 this.queue.push(x)

};

/**
 * Removes the element from in front of this.queue and returns that element.
 * @return {number}
 */
MyQueue.prototype.pop = function() {
return this.queue.shift()
};

/**
 * Get the front element.
 * @return {number}
 */
MyQueue.prototype.peek = function() {
 return this.queue[0]
};

/**
 * Returns whether the this.queue is empty.
 * @return {boolean}
 */
MyQueue.prototype.empty = function() {
if(this.queue.length===0)
{
    return true
}
return false
};

/**
 * Your MyQueue object will be instantiated and called as such:
 * var obj = new MyQueue()
 * obj.push(x)
 * var param_2 = obj.pop()
 * var param_3 = obj.peek()
 * var param_4 = obj.empty()
 */

63.每日温度

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WXc2NCif-1634807680198)(算法题练习.assets/image-20210830232202139.png)]

/**
 * @param {number[]} temperatures
 * @return {number[]}
 */
var dailyTemperatures = function(temperatures) {
let res=[]
for(let i=0;itemperatures[i]){
            count=j-i
            break
        }
    }
    res[i]=count
}
return res
};

64.回文链表

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-quxGRcxk-1634807680198)(算法题练习.assets/image-20210830232917507.png)]

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @return {boolean}
 */
//  思路:把链表中的值加入到数组中去,然后对数组使用双指针判断数组元素是否为回文
var isPalindrome = function(head) {
let curr=head
let res=[]
while(curr){
    res.push(curr.val)
    curr=curr.next
}
let i=0,j=res.length-1
while(i<=j){
    if(res[i]!==res[j]){
return false
    }
    i++
    j--
}
return true
};

65.最小栈

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V0JsqNFS-1634807680198)(算法题练习.assets/image-20210831000644215.png)]

/**
 * initialize your data structure here.
 */
var MinStack = function() {
this.stack=[]
this.minStack=[]
};

/** 
 * @param {number} val
 * @return {void}
 */
MinStack.prototype.push = function(val) {
this.stack.push(val)
// 最小栈的最后一个元素存放着当前数组的最小的元素,每一个新增的元素都要与最小栈的最后一个元素比较,取他们之前较小的添加到末尾,刚开始该栈中一个没有一个元素,如果设为0,则多一个元素,当添加2,3进去,那么取最小值就是0,不符合题意
this.minStack.push(Math.min(this.minStack[this.minStack.length-1],val))
};

/**
 * @return {void}
 */
MinStack.prototype.pop = function() {
this.stack.pop()
// 当栈中的栈顶元素删除之后,那么最小的应该是倒数第二位,所以最小值也需要删除最后一位。
// 如-2,0,-3进入栈中【-2,0,-3】,最小栈【-2,-2,-3】,当删掉栈中最后一位之后,它的最小值也就变了,是删掉之后栈中的最小值
this.minStack.pop()
};

/**
 * @return {number}
 */
MinStack.prototype.top = function() {
return this.stack[this.stack.length-1]

};

/**
 * @return {number}
 */
MinStack.prototype.getMin = function() {
//     let stacks=[...this.stack]
// stacks.sort((a,b)=>a-b)
// return stacks[0]
return this.minStack[this.minStack.length-1]
};

/**
 * Your MinStack object will be instantiated and called as such:
 * var obj = new MinStack()
 * obj.push(val)
 * obj.pop()
 * var param_3 = obj.top()
 * var param_4 = obj.getMin()
 */

66.多数元素[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AXn31qFT-1634807680199)(算法题练习.assets/image-20210831003844137.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8zp1EPhY-1634807680200)(算法题练习.assets/image-20210831003851073.png)]

/**
 * @param {number[]} nums
 * @return {number}
 */
var majorityElement = function(nums) {
let map =new Map()
for(let i=0;iMath.floor(nums.length/2)){
        return nums[i]
    }
}
// nums.sort((a,b)=>b-a)
// return nums[Math.floor(nums.length/2)]
};

67.只出现一次的数字

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iQN8shKz-1634807680201)(算法题练习.assets/image-20210831005635684.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YikgvsuX-1634807680202)(算法题练习.assets/image-20210831120810617.png)]

/**
 * @param {number[]} nums
 * @return {number}
 */
//  注意这个题说了其他元素均出现两次
var singleNumber = function(nums) {
    let set=new Set()
for(let i=0;i

68.最长公共前缀

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lwU8TQaU-1634807680202)(算法题练习.assets/image-20210831142633900.png)]

/**
 * @param {string[]} strs
 * @return {string}
 */
var longestCommonPrefix = function(strs) {
    // 方法一
//     for(let i=strs[0].length;i>=0;i--){
//      if(strs.every(values=> values.indexOf(strs[0].slice(0,i))===0)){

//          return strs[0].slice(0,i)
//      }   
     
// } 
// return ""  
        // 方法二
    let an=strs[0]
    for(let i=0;i

69.整数反转

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3RGK5pzk-1634807680203)(算法题练习.assets/image-20210831150336305.png)]

/**
 * @param {number} x
 * @return {number}
 */
var reverse = function (x) {
if(x===0){
    return x
}
if(xMath.pow(2,31)-1){
    return 0
}
let y=0
if(x>0){
    while(x>0){
        y=y*10+x%10
        x=Math.floor(x/10)
    
    }
        // 根据题目要求翻转后整数有范围限制
        if(yMath.pow(2,31)-1){
    return 0
}
    return y
}
if(x<0){
    x=-x
    while(x>0){
        y=y*10+x%10
        x=Math.floor(x/10)
   
    }         if(yMath.pow(2,31)-1){
    return 0
}
    return -y
}
};

70.实现一个简单的模板替换方法template(str,obj)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nYNLqWSc-1634807680203)(算法题练习.assets/image-20210901222802850.png)]

var render = function (str, data) {
  const keys = Object.keys(data);
  // console.log(keys);
  // console.log(keys[0]);
  const dataList = keys.map(function (key) {
    return data[key];
  });
  // new RegExp("\\$\\{" + keys[i] + "\\}", "gm")
  console.log(dataList);
  for (var i = 0; i < keys.length; i++) {
    str = str.replace(
      new RegExp("\\{" + keys[i] + "\\}", "g"),
      dataList[i]
    );
  }
  return str;
};
var result = render(url, {
  b: "l",
  h: "g"
});

console.log(result);

71.连续展示m天的数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5Q7mDbjb-1634807680203)(算法题练习.assets/image-20210903133939527.png)]

let s = []
for (let i = 0; i < 11; i++) {
  let b = i <= 9 ? "0" + i : i
  let a = `2021-09-${b}`
  s.push({ date: a, pv: 0 })
}
let s1 = [{ date: '2021-09-01', pv: 1000 }, { date: '2021-09-03', pv: 1000 }]

s.forEach((value, index, arr) => {
  // 方法一:这里不能直接通过给value赋值的方式改变数组元素,需要通过数组的下标值来赋值改变
  // for (let i = 0; i < s1.length; i++)
  //   if (value.date === s1[i].date) {
  //     // console.log(value);
  //     // console.log(s1[i]);
  //     arr[index] = s1[i]
  //     // console.log(value);
  //   }
  s1.forEach(item => {
    if (value.date === item.date) {
      arr[index] = item
    }
  })
})

// console.log(s.includes(s1));
console.log(s);

[
  { date: '2021-09-00', pv: 0 },
  { date: '2021-09-01', pv: 1000 },
  { date: '2021-09-02', pv: 0 },
  { date: '2021-09-03', pv: 1000 },
  { date: '2021-09-04', pv: 0 },
  { date: '2021-09-05', pv: 0 },
  { date: '2021-09-06', pv: 0 },
  { date: '2021-09-07', pv: 0 },
  { date: '2021-09-08', pv: 0 },
  { date: '2021-09-09', pv: 0 },
  { date: '2021-09-10', pv: 0 }
]

72.斐波那契数列

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NliQCuEn-1634807680203)(算法题练习.assets/image-20210903230510756.png)]

/**
 * @param {number} n
 * @return {number}
 */
 0,1,1,2,3,5
var fib = function(n) {
let n0=0,n1=1,sum
for(let i=0;i

73.约瑟夫环问题

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dFcXHuIt-1634807680204)(算法题练习.assets/image-20210904003539917.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aB4P6epi-1634807680205)(算法题练习.assets/image-20210904003613786.png)]

var lastRemaining = function(n, m) {
let res = 0;
    for (let i = 2; i <= n; i++) {
        res = (res + m) % i;
        console.log(res)
    }
    return res;
};

74.回文数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wKtZFf5G-1634807680206)(算法题练习.assets/image-20210904162623208.png)]

/**
 * @param {number} x
 * @return {boolean}
 */
var isPalindrome = function(x) {
let b=x.toString().split("")
function isPalindString(str){
    let l=0,r=str.length-1
    while(l<=r){
        if(str[l]!==str[r]){
            return false
        }
        l++;
        r--
    }
    return true
}
return  isPalindString(b)
};

75.删除有序数组中的重复项

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RGmcSwl7-1634807680206)(算法题练习.assets/image-20210904172609920.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1Bod1xzz-1634807680206)(算法题练习.assets/image-20210904172532674.png)]

/**
 * @param {number[]} nums
 * @return {number}
 */
var removeDuplicates = function(nums) {
let i=0
for(let j=1;j

76.位1的个数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RochZ3gJ-1634807680207)(算法题练习.assets/image-20210904173306962.png)]

/**
 * @param {number} n - a positive integer
 * @return {number}
 */
var hammingWeight = function(n) {
    let count=0
    while(n){
        if(n&1===1){
            count++
        }
        n=n>>>1
    }
    return count
};

77.字符串中相同字符之间的最短距离

function x(str) {
  let minLength = str.length - 1
  let map = new Map()
  for (let i = 0; i < str.length; i++) {
    if (!map.has(str[i])) {
      map.set(str[i], i)
    }
    else {
      minLength = Math.min(minLength, i - map.get(str[i]))
      map.delete(str[i])
      map.set(str[i], i)
    }
  }
  return minLength
}
console.log(x("你是谁,你是你"));
------
2

78.时针和分针的夹角

function x(str) {
  let p = str.split(":")
  let h = p[0]
  let m = p[1]
  if (h < 24 && m < 60) {
    let n1 = h % 12 * 30 + m * 0.5
    let n2 = m * 6
    let r = Math.abs(n1 - n2)
    return Math.floor(r)
  }
}
console.log(x("01:50"));

79.丢失的数字

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HTVyCWVs-1634807680222)(算法题练习.assets/image-20210904233336254.png)]

/**
 * @param {number[]} nums
 * @return {number}
 */
var missingNumber = function(nums) {
// let set=new Set()
// for(let i=0;ipre+val,0)
};

80.删除字符串中所有相邻的重复项

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RmubVBq8-1634807680222)(算法题练习.assets/image-20210904234714306.png)]

/**
 * @param {string} s
 * @return {string}
 */
var removeDuplicates = function(s) {
let stack=[]
for(let ch of s){
    // 巧妙的运用了栈的特点,首先把元素入栈,如果新的元素的栈中的栈顶元素相等,那么则出栈,否则进栈
    if(stack.length&&stack[stack.length-1]===ch){
        stack.pop()
    }
    else{
        stack.push(ch)
    }
}
return stack.join("")
};

81.重复的字符串

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m045vANR-1634807680223)(算法题练习.assets/image-20210904235230631.png)]

let a = "21"

function x(str) {
  let result = str + str
  let result1 = result.substring(1, result.length - 1)
  console.log(result1);
  return result1.indexOf(str) !== -1 ? true : false
}
console.log(x("abab"));

82.数组中出现次数超过一半的数字

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9tsYVad7-1634807680224)(算法题练习.assets/image-20210905000313453.png)]

/**
 * @param {number[]} nums
 * @return {number}
 */
var majorityElement = function(nums) {
let stack=[]

for(let ch of nums){
    if(stack.length===0){
stack.push(ch)
continue
    }
    if(stack[stack.length-1]===ch){
        stack.push(ch)
    }
    else{
stack.pop()
    }
}
return stack[stack.length-1]
};

83。翻转字符串

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3Dq6dpv9-1634807680224)(算法题练习.assets/image-20210905000639570.png)]

84.扑克牌中的顺子

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Do9GzNsH-1634807680224)(算法题练习.assets/image-20210905164424568.png)]

/**
 * @param {number[]} nums
 * @return {boolean}
 */
var isStraight = function(nums) {
let max=0,min=14
let set=new Set()
for(let k of nums){
    if(k===0){
        continue
    }
max=Math.max(max,k)
min=Math.min(min,k)
if(!set.has(k)){
    set.add(k)
}
else {
    return false
}
}
return max-min<5
};

85.连续子数组的最大和

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OZftqOKp-1634807680224)(算法题练习.assets/image-20210905165315054.png)]

/**
 * @param {number[]} nums
 * @return {number}
 */
var maxSubArray = function(nums) {
let pre=0,maxAns=-100
nums.forEach(item=>{
    pre=Math.max(item,pre+item)
    maxAns=Math.max(maxAns,pre)
})
return maxAns
};

86.跳跃游戏

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EW9wcHQx-1634807680225)(算法题练习.assets/image-20210905232653768.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ERdd26OR-1634807680225)(算法题练习.assets/image-20210905232642615.png)]

/**
 * @param {number[]} nums
 * @return {boolean}
 */
var canJump = function(nums) {
let n=nums.length;
// cover记录当前位置能够调到最大的位置
let cover=0
for(let i=0;i<=cover;i++){//这里cover要随时更新,
  cover=Math.max(cover,i+nums[i])  
if(cover>=nums.length-1){
    return true
}

}
return false
};

87.反转字符串中单词111

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PozNwoIm-1634807680226)(算法题练习.assets/image-20210905233858415.png)]

/**
 * @param {string} s
 * @return {string}
 */
var reverseWords = function(s) {
let ss=s.split(" ")
let result=[]
ss.forEach((item,index,arr)=>{
   result.push(arr[index].split("").reverse().join(""))
   
})
return result.join(" ")
};

88.两数之和,有序数组

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dn3SLghz-1634807680226)(算法题练习.assets/image-20210906001203059.png)]

/**
 * @param {number[]} numbers
 * @param {number} target
 * @return {number[]}
 */
var twoSum = function(numbers, target) {
    // 方法一
// for(let i=0;itarget){
        r--
    }
    else if(numbers[l]+numbers[r]

89.二叉树的最小深度

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Dib8jK3Z-1634807680226)(算法题练习.assets/image-20210906001910921.png)]

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number}
 */
var minDepth = function(root) {
if(!root){
    return 0
}
if(!root.left&&!root.right){
    return 1
}
let ans=100000
if(root.left){
 ans=Math.min(minDepth(root.left) ,ans)   
}
if(root.right)
{
    ans=Math.min(minDepth(root.right),ans)
}


return ans+1
};

90.将有序数组转换为二叉搜索树

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cilapqie-1634807680227)(算法题练习.assets/image-20210906003829762.png)]

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {number[]} nums
 * @return {TreeNode}
 */
var sortedArrayToBST = function(nums) {
function buildTree(arr,left,right){
    if(left>right){
        return null
    }
    let mid= Math.floor(left +(right-left)/2)
    let root=new TreeNode(arr[mid])
    root.left=buildTree(arr,left,mid-1)
    root.right=buildTree(arr,mid+1,right)
    return root
}
return buildTree(nums,0,nums.length-1)
};

91.和为s的连续正数序列

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yy2Z1K4V-1634807680228)(算法题练习.assets/image-20210906131518107.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ezb1O8j5-1634807680229)(算法题练习.assets/image-20210906131522943.png)]

/**
 * @param {number} target
 * @return {number[][]}
 */
var findContinuousSequence = function(target) {
let l=1,r=2,sum=3;
let result=[]
while(ltarget){
    // 大于的情况下,缩小窗口,先减去l,再l++
    sum=sum-l
    l++
}
else{
    // 小于的情况,先r++,在sum再加上新的r
    r++
    sum=sum+r
}
}
return result
};

92.二叉搜索树的最小绝对差

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q5MTktt1-1634807680229)(算法题练习.assets/image-20210906135535497.png)]

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number}
 */
var getMinimumDifference = function(root) {
let result=[]
function buildTree(root){
    if(root){
        // 通过中序遍历,把二叉搜索树的值按升序排列添加进数组中
        buildTree(root.left)
        // 注意:这里是节点的值,而不是节点
        result.push(root.val)
        buildTree(root.right)
    }
}
buildTree(root)
console.log(result)
let min=result[result.length-1]
// 这里遍历i要从1开始,因为下面判断的是i,不是i+1,不然当i=result.length,就不符合循环条件 了
for(let i=1;i

93.杨辉三角

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-U9MfvSsy-1634807680230)(算法题练习.assets/image-20210906143154469.png)]

/**
 * @param {number} numRows
 * @return {number[][]}
 */
var generate = function(numRows) {
const ret=[]
for(let i=0;i

94.整数分解成任意几个整数的和

var num = 4;
var arr = [];
// summation(num, 1, 0)
function summation(n, m, s) {
  if (n > 0) {
    for (var i = m; i <= n; i++) {
      arr[s] = i;

      summation(n - i, i, s + 1)
    }
    return;
  }
  console.log(s)
  console.log(arr)
  if (arr[0] == num) {
    return;
  }
  var sum = '';
  sum = num + '=' + arr[0];
  for (var k = 1; k < s; k++) {
    sum += '+' + arr[k]
  }
  console.log(sum);
}
summation(num, 1, 0)

95.最长连续递增序列长度

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xFHlPSAR-1634807680230)(算法题练习.assets/image-20210906171032848.png)]

/**
 * @param {number[]} nums
 * @return {number}
 */
var findLengthOfLCIS = function(nums) {
let count=1
let maxLength=0
for(let i=0;inums[i]){
        count++
        continue//当下一个值大于当前值时,计数器加一,继续下一次循环
    }
    // 当不等于时,取计数器的值,得到最大长度
maxLength=Math.max(maxLength,count)
// 计数器重新置为1
count=1
}
return maxLength
};

96.下一座更高的山

function x(str) {
  console.log(str);
  let result = []
  for (let i = 0; i < str.length; i++) {
    let flag = false
    for (j = i + 1; j < str.length; j++) {
      if (str[j] > str[i]) {
        result[i] = j - i;
        flag = true
        break
      }
    }
    if (!flag || i === str.length - 1)
      result[i] = 0
  }
  console.log(result);
}
x([2, 0, 1, 3, 5, 1, 1, 7, 3, 3])

97.归并排序,快速排序,冒泡排序

function mergeSort(arr) {
  // 这里是合并两个数组的函数
  function merge(left, right) {
    let arr = []
    while (left.length && right.length) {
      if (left[0] < right[0]) {
        arr.push(left.shift())
      }
      else {
        arr.push(right.shift())
      }
    }
    return [...arr, ...left, ...right]
  }
  // 下面是分数组的过程
  let mid = Math.floor(arr.length / 2)
  if (arr.length < 2) {
    return arr
  }
  let left = arr.splice(0, mid)
  return merge(mergeSort(left), mergeSort(arr))
}
let b = mergeSort([2, 1, 4, 2, 1, 3, 5, 1, 2, 7, 9])
console.log(b);
function quickSort(arr) {
  if (arr.length < 2) {
    return arr
  }
  let left = [], right = [];
  // 这里的基准值要取出来,不然一直在数组中会重复
  let baseVal = arr.shift()
  arr.forEach(item => {
    if (item < baseVal) {
      left.push(item)
    }
    else {
      right.push(item)
    }
  })
  return [...quickSort(left), baseVal, ...quickSort(right)]
}
let c = quickSort([2, 1, 4, 3, 3, 2, 4, 2, 5, 6, 2])
console.log(c);
// ------------
function bubbleSort(arr) {
  for (let i = 0; i < arr.length; i++) {
    // i为排序的趟数,每一趟都把最大的数排序到数组的最后,下一趟就不用遍历到上一趟排序出来的位置
    for (let j = 0; j < arr.length - i; j++) {
      if (arr[j] > arr[j + 1]) {
        [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]]
      }
    }
  }
  return arr
}
let d = bubbleSort([5, 4, 3, 2, 1, 9, 8, 7, 6])
console.log(d);

98.对象按属性值排序

let a = {
  a: 99,
  b: 67,
  c: 48,
  d: 67,
  w: 34,
  f: 34,
  j: 56,
  s: 54
}
let newvalues = Object.values(a).sort((a, b) => b - a)
// console.log(newKeys);
let newObj = {}
newvalues.forEach(item => {
  Object.keys(a).forEach(key => {
    if (a[key] === item) {
      newObj[key] = item
    }
  })

})
console.log(newObj);
{ a: 99, b: 67, d: 67, j: 56, s: 54, c: 48, w: 34, f: 34 }

99.删除字符串中的空格

let a = " sfsd dsf f        "
let s = a.replace(/(^\s*)|(\s*$)/g, "")//删除字符串前后的空格,trim方法
let s1 = a.replace(/(\s*) /g, "")//删除字符串中所有的空格
let s2 = a.replace(/[ ]/g, "")
let strs = str.replace(/ /g, "");
console.log(s2);
console.log(s1);
console.log(s, "d");
console.log(a.trim(), "d");
sfsddsff
sfsddsff
sfsd dsf f d
sfsd dsf f d

100.js递归+数据缓存实现斐波拉契函数

// let obj = {
//   1: 1,
//   2: 1
// }
let obj = [0, 1, 1]
function f(n) {
  if (obj[n]) {
    return obj[n]
  }
  obj[n] = f(n - 1) + f(n - 2)
  return obj[n]
}
console.log(f(4));
console.log(obj);
3
[ 0, 1, 1, 2, 3 ]

101.手动实现map

Array.prototype.Map = function (fn, context) {
  let result = []//map方法返回一个新的数组
  for (let i = 0; i < this.length; i++) {
    // 把函数的this指向新的对象,执行函数
    let results = fn.call(context, this[i], i, this)
    result.push(results)
  }
  return result
}
let a = [1, 2, 3, 4]
let b = a.Map((item, index, arr) => console.log(item, index, arr))

102.实现一个方法,来判断正整数是为2的整数次幂

function x(n) {
  while (n != 2) {
    let a = n / 2
    // console.log(a);
    if (a % 2 !== 0) {
      return false
    }
    n = a
  }
  return true
}
console.log(x(16));
function y(n) {
  return (n & (n - 1)) === 0
}
console.log(y(7));

103。在一组文件路径集合中,找出那些存在子路径的集合并返回


function find(str) {
  let strArr = str.split(",")
  let tempArr = [...strArr]
  let ans = []
  console.log(strArr);
  strArr = strArr.sort((a, b) => a.length - b.length)
  console.log(strArr);
  if (!(strArr.length > 1)) {
    return ""
  }
  for (let i = 0, j = strArr.length - 2; i < j; i++) {
    let lastItem = strArr.pop()

    let temp = strArr.filter(item => {
      let notEqual = item.split("/").length !== lastItem.split("/").length

      return notEqual && lastItem.includes(item)
    })
    console.log(temp);
    ans = [...new Set([...ans, ...temp])]
  }
  console.log(ans);
  let result = tempArr.filter(item => {

    return ans.includes(item)
  }).join(",")
  if (!result) {
    return false
  }
  return result
}

console.log(find("/a/c, /a/d, /x/y / z / b, /x/y / z, /x/y"));

104.十六进制颜色改成rgb

function hexToRgb(hex) {
  if (hex.charAt(0) === "#") {
    console.log(hex);
    hex = hex.substr(1)
  }
  if (hex.length !== 3 && hex.length !== 6) {
    return hex
  }
  if (hex.length === 3) {
    hex = hex.split("").map(c => c.repeat(2)).join("")
    console.log(hex);
  }
  let red = parseInt(hex.substring(0, 2), 16)
  let blue = parseInt(hex.substring(4, 6), 16)
  let green = parseInt(hex.substring(2, 4), 16)
  return `rgb(${red}, ${green}, ${blue})`
}
console.log(hexToRgb("#FFF"));
rgb(255, 255, 255)

105.数组转树结构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PCvQRGpm-1634807680230)(算法题练习.assets/image-20210926130644598.png)]

  function list_to_tree(list) {
    let result = []
    let map = {}
    // 通过map建立数组中id与所在位置的对象表,加快寻址速度,避免每次找父节点都需要遍历数组
    for (let i = 0; i < list.length; i++) {
      map[list[i].id] = i
      list[i].children = []
    }
    console.log("map");//Object { 6: 1, 7: 2, 9: 3, 11: 4, 12: 0 }
    for (let i = 0; i < list.length; i++) {
      let node = list[i]
      if (node.parentId !== "0") {//如果元素的parentId不等于0,则添加到父元素中
        list[map[list[i].parentId]].children.push(node)
        console.log(result);
      }
      else {//如果元素的parentId等于0,则直接加入到结果数组中
        result.push(node)
      }
      // console.log(result);
    }
    return result
    // console.log(map);
    // console.log(list);
  }

  console.log(list_to_tree(b));
 function list_to_tree(list) {
    let result = []
    for (let i = 0; i < list.length; i++) {
      let node = list[i]
      // console.log(node.id);
      node.children = []
      if (node.parentId !== "0") {
        for (let j = 0; j < list.length; j++) {
          console.log(node.id, list[j].parentId);
          // console.log(list[j].parentId);
          if (list[j].id === node.parentId) {
            // console.log("1");
            list[j].children.push(node)
          }
        }
      }

      else {
        result.push(node)
      }

    }
    return result
  }

106.合并两个有序数组

function x(a, b) {
  let n = a.length, m = b.length
  let i = 0, j = 0
  let result = []
  while (i < n && j < m) {
    if (a[i] < b[j]) {
      result.push(a[i++])
    }
    else {
      result.push(b[j++])
    }
  }
  while (i < n) {
    result.push(a[i++])
  }
  while (j < m) {
    result.push(b[j++])
  }
  return result
}

107.找出数组中某个数据最大连续出现的次数


let a = [1, 3, 5, 5, 5, 7, 7, 7, 7, 7, 9, 7]
function x(arr, n) {
  let Maxlength = 0
  for (let i = 0; i < arr.length; i++) {
    length = 0
    while (arr[i] === n) {
      length++
      i++
    }
    Maxlength = Math.max(length, Maxlength)
  }
  return Maxlength
}
// function x(arr) {
//   let maxLength = 0
//   for (let i = 0; i < arr.length; i++) {

//     for (let j = i + 1; j < arr.length; j++) {
//       if (arr[i] === arr[j]) {
//         // console.log(j);
//         // console.log(arr[i], arr[j]);
//         continue

//       }
//       else {
//         maxLength = Math.max(j - i, maxLength)
//         break
//       }
//     }
//   }
//   return maxLength
// }

108.当数组中出现连续元素时用“-”输出

原数组:
[1,2,3,4,6,8,9,10]
期望结果:
[“1-4”,6,“8-10”]

function x(arr) {
  let result = []
  let start
  arr.forEach((item, index) => {
    // console.log(arr[index - 1]);这里分三种情况,当前元素+1等于下一个元素并且当前元素-1不等于上一个元素,则作为起始区间,
    //这里第一个元素满足第一个if条件语句
    if (item + 1 === arr[index + 1] && item - 1 !== arr[index - 1]) {
      start = item
    }
    // 当满足当前元素-1等于前一个元素并且当前元素+1不等于下一个元素时,最后一个元素也满足该条件则该元素是结束区间,则把该区间添加到结果数组中
     else if (item - 1 === arr[index - 1] && item + 1 !== arr[index + 1]) {
      result.push(start + "-" + item)
    }
    // 当当前元素-1不等于上一个元素并且当前元素+1不等于下一个元素,则直接添加到结果数组中去
    else if (item - 1 !== arr[index - 1] && item + 1 !== arr[index + 1]) {
      result.push(item)
    }
  })
  return result
}

109.求两个字符串中最长的公共子串

function longestString(str1, str2) {
  // 首先对两个字符串排序,把较小的字符串当做第一个字符串
  if (str1.length > str2.length) {
    [str1, str2] = [str2, str1]
  }
  console.log(str1, str2);
  // 思路:把较小的字符串截取从两端开始截取字符串,那么第一个截取出来的字符串如果存在于第二个字符串中,那么截取的字符串就是
  // 所求的最大公共子串
  for (let j = str1.length; j >= 0; j--) {
    for (let i = 0; i < j; i++) {
      if (str2.indexOf(str1.substring(i, j)) !== -1) {
        return str1.substring(i, j)
      }
    }
  }
}
let s1 = "1232aaa3333", s2 = "aa3333444"
let b = longestString(s1, s2)
console.log(b);
------
aa3333444 1232aaa3333
aa3333

110.手动实现一个hash路由

 // 手动实现一个hash路由
  (function () {
    var router = function () {
      // 用于存放一个路由与执行函数的键值对对象
      this.routers = {}
      // 记录当前的URL
      this.currentUrl = ""
    }
    // 初始化,给window绑定一个hashchange事件,当hash改变的时候会触发该事件
    router.prototype.init = function () {
      window.addEventListener("hashchange", this.readload.bind(this))
    }
    // 这是回调函数,找到当前URL对应的回调函数并且执行
    router.prototype.readload = function () {

      this.currentUrl = location.hash.substring(1) || "/"
      this.routers[this.currentUrl]()
    }
    // 注册url 与回调函数
    router.prototype.map = function (key, callback) {
      this.routers[key] = callback
    }
    let routers = new router()
    routers.init()

    routers.map("/s", function () {

      document.querySelector("#boxs").innerHTML = "主页"


    })

    routers.map("/footer", function () {

      document.querySelector("#boxs").innerHTML = "底部"


    })
    routers.map("/head", function () {

      document.querySelector("#boxs").innerHTML = "头部"

    })
  })()
  document.querySelector("#boxs").innerHTML
  console.log(document.querySelector("#boxs").innerHTML)

111.找出字符串中出现次数最多的字符

let s = "A,a,a,a,a,a,B,a,D,C,D,D,D"
function x(str) {
  let res = str.split(",")
  let obj = {}
  for (let i = 0; i < res.length; i++) {
    if (!obj[res[i]]) {
      obj[res[i]] = 1
    }
    else {
      obj[res[i]]++
    }
  }

  console.log(obj);
  let max = 0
  for (let item in obj) {
    max = Math.max(obj[item], max)
  }

  for (let item in obj) {
    if (obj[item] === max) {
      console.log(item, max);
      return item
    }
  }

  // res.sort()
  // console.log(res);
  // let mid = Math.floor(res.length / 2)

  // return res[mid]
}
console.log(x(s));
{ A: 1, a: 6, B: 1, D: 4, C: 1 }
a 6
a

112.最长递增子序列

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8YhiZPhQ-1634807680232)(算法题练习.assets/image-20210928000806886.png)]

var lengthOfLIS = function(nums) {
    // 建立一个数组,每个元素对应的数是1
let dp=new Array(nums.length).fill(1)
console.log(dp)
let max=1
for(let i=1;inums[j]){
            dp[i]=Math.max(dp[i],dp[j]+1)
        }
    }
max=Math.max(dp[i],max)
}
return max
};

113.数组乱序

function shuffle(arr) {
  let newArr = Array.prototype.slice.call(arr)
  let temp = 0
  for (let i = newArr.length - 1; i > 0; i--) {
    temp = Math.floor(Math.random() * i);
    // console.log(temp);
    [newArr[temp], newArr[i]] = [newArr[i], newArr[temp]]
  }
  return newArr
}
let arr = [1, 2, 3, 4, 5, 6]
console.log(shuffle(arr));
[ 4, 5, 2, 3, 6, 1 ]
// let a = [1, 2, 3].map(item => parseInt(item, 10))
// console.log(a);
let a = [1, 2, 3, 4, 5]
// a.sort(() => Math.random() - 0.5)
// console.log(a);
// function randomArr(arr) {
//   let result = []
//   while (arr.length > 0) {
//     let i = Math.floor(Math.random() * arr.length)
//     result.push(arr[i])
//     arr.splice(i, 1)
//   }
//   return result
// }
// console.log(randomArr(a));

114.两个数组的交集

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NLFWVTrN-1634807680232)(算法题练习.assets/image-20211003144009333.png)]

/**
 * @param {number[]} nums1
 * @param {number[]} nums2
 * @return {number[]}
 */
var intersect = function(nums1, nums2) {
if(nums1.length

115.合并两个有序数组

/**
 * @param {number[]} nums1
 * @param {number} m
 * @param {number[]} nums2
 * @param {number} n
 * @return {void} Do not return anything, modify nums1 in-place instead.
 */
var merge = function(nums1, m, nums2, n) {
let l1=m-1
let l2=n-1
let l3=m+n-1
//从每个数组的最后一个元素开始比较,把较大的放在后面
while(l1>=0&&l2>=0){
    nums1[l3--]=nums1[l1]>nums2[l2]?nums1[l1--]:nums2[l2--]
}
// 当有一个数组的元素全部添加进数组后,则向数组中添加剩余l2的元素
nums1.splice(0,l2+1,...nums2.slice(0,l2+1))
return nums1
};

116.输入aaaabbbccd,输出a4b3c2d

let str = "aaaabbbccd"
function sample(str) {
  let obj = {}
  for (let i = 0; i < str.length; i++) {
    if (!obj[str[i]]) {
      obj[str[i]] = 1
    }
    else {
      obj[str[i]]++
    }
  }
  let s = ""
  for (let i in obj) {
    if (obj[i] === 1) {
      s = s + i
    }
    else {
      s = s + i + obj[i]
    }
  }
  console.log(s);
}
sample(str)

117.独一无二出现的数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N4huMKER-1634807680232)(算法题练习.assets/image-20211005161338784.png)]

/**
 * @param {number[]} arr
 * @return {boolean}
 */
var uniqueOccurrences = function(arr) {
    let obj={}
let set =new Set()
for(let i=0;i

实现可迭代接口

// 实现可迭代接口
// 创建一个实现iterable接口的自定义对象
let obj = {
  store: ["foo", "bar", "baz"],
  // 实现iterable接口就是向当前对象挂载iterator()方法,该方法可以通过 Symbol.iterator 常量来实现
  [Symbol.iterator]: function () {
    let index = 0
    const self = this
    // 返回一个实现迭代器的对象,该对象提供next()方法
    return {
      // next()方法用来向后迭代的逻辑
      next: function () {
        // 返回一个迭代结果的对象,这个迭代结果对象包含两个成员,一个是 value 表示当前迭代的结果,一个是 done 表示当前是否迭代完成
        const result = {
          value: self.store[index],
          done: index >= self.store.length
        }
        index++
        return result
      }
    }
  }
}
for (let item of obj) {
  console.log(item);
}

118.简化数组

mergeDeepList([{id: 1}, {id: 3, pid: 1}, {id:4}]) 
//=> [{id:1, children: [{id:3}]}, {id:4}]
  //=> [{id:1, children: [{id:3}]}, {id:4}]
  // function mergeDeepList(arr) {

  //   //   for(let i=0;i

119.获取URL的query参数

let s = "https://www.example.com/test.html?a=param1&b=param2"
function parseSearchParams(searchParamsString) {
  // return searchParamsString.split('&').reduce((searchParams, curKV) => {
  //   const [k, v] = curKV.split('=').map(decodeURIComponent);
  //   searchParams[k] = v;

  //   return searchParams;
  // }, {});
  let index = searchParamsString.indexOf("?")
  let ss = searchParamsString.substr(index + 1)
  return ss.split("&").reduce((total, currentValue) => {
    const [k, v] = currentValue.split("=")
    total[k] = v
    return total
  }, {})
}
let b = parseSearchParams(s)
console.log(b);
{ a: 'param1', b: 'param2' }

120.全排列

let func = (arr) => {
  let len = arr.length
  let res = [] // 所有排列结果
  /**
   * 【全排列算法】
   * 说明:arrange用来对arr中的元素进行排列组合,将排列好的各个结果存在新数组中
   * @param tempArr:排列好的元素
   * @param leftArr:待排列元素
   */
  let arrange = (tempArr, leftArr) => {
    if (tempArr.length === len) { // 这里就是递归结束的地方
      // res.push(tempArr) // 得到全排列的每个元素都是数组
      console.log(tempArr, leftArr, "sdfasdasd");
      res.push(tempArr) // 得到全排列的每个元素都是字符串
    } else {
      leftArr.forEach((item, index) => {
        let temp = [].concat(leftArr)
        temp.splice(index, 1)
        console.log(tempArr);
        // 此时,第一个参数是当前分离出的元素所在数组;第二个参数temp是传入的leftArr去掉第一个后的结果
        arrange(tempArr.concat(item), temp) // 这里使用了递归
        console.log(tempArr, item, index, temp);
      })
    }
  }
  arrange([], arr)
  // return res
}
console.log('结果:', func(['A', 'B', 'C', 'D']))

121.删除超过三个以上的0

const data = [1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 5, 2, 0, 0, 0, 1, 0, 0, 0, 2];
//去除三个及以上相邻的0
//返回结果:[1,2,3,5,2,0,1,0,0,2]
function unique(arr) {
  for (let i = 0; i < arr.length; i++) {
    if (arr[i] === arr[i + 1] && arr[i] === arr[i + 2]) {
      arr.splice(i, 3)


      while (arr[i] === 0) {
        arr.splice(i, 1)
        // i--
      }
      i--
    }
  }
  return arr
}
console.log(unique(data));

122.最长无重复子串

var lengthOfLongestSubstring = function (s) {
  let set = new Set()
  let j = 0;
  let maxLength = 0
  let obj = {}
  for (let i = 0; i < s.length; i++) {
    if (!set.has(s[i])) {
      set.add(s[i]);
      maxLength = Math.max(maxLength, set.size)


      obj[set.size] = [...set]
    }
    else {
      while (set.has(s[i])) {
        set.delete(s[j])
        j++
      }
      set.add(s[i])
    }
  }
  console.log(obj[maxLength].join(""));
  console.log(obj)
  // let b=set.toString()
  // console.log(set)
  return maxLength


};
lengthOfLongestSubstring("abcabcbb")
abc
{ '1': [ 'a' ], '2': [ 'a', 'b' ], '3': [ 'a', 'b', 'c' ] }

123.字符中存在abb样式的子序列的个数

subStr("abcbcc")
0, 1, 2, 2, 3, 3
function subStr(s) {
  let res = 0, dis = new Array(100).fill(0)
  // 这一轮循环是找到每个元素在该元素之前的与该元素不相同的元素的个数,
  for (let i = 1; i < s.length; i++) {
    for (let j = 0; j < i; j++) {
      if (s[i] !== s[j]) {
        dis[i]++
      }
    }
  }
  console.log(dis);
  // for (let i = s.length - 1; i >= 2; i--) {
  //   for (let j = 0; j < i; j++) {
  //     if (s[i] == s[j]) {
  //       res += dis[j]
  //     }
  //   }
  // }
  // 这次循环是从第三个元素开始,分别对该元素之前的元素比较,如果与之前的元素相等,那么之前的元素所对应的就是可以组成abb样式的
  for (let i = 2; i < s.length; i++) {
    for (let j = 0; j < i; j++) {
      if (s[i] === s[j]) {
        res += dis[j]
      }
    }
  }
  console.log(res);
}
8

124.整数转Ipv4

function numTipv4(num) {
  let ip1 = (num >>> 24) & 0xff;
  let ip2 = (num >>> 16) & 0xff;
  let ip3 = (num >>> 8) & 0xff
  let ip4 = num & 0xff
  // console.log( & 0xff);
  return ip1 + "." + ip2 + "." + ip3 + "." + ip4
}
console.log(numTipv4(67305985));//4.3.2.1

125.最大数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LUs7L6uE-1634807680233)(算法题练习.assets/image-20211016010019220.png)]

var largestNumber = function(nums) {
let s= nums.sort((a, b) => (a + "" + b) - (b + "" + a)).reverse().join("")
return s.startsWith("0")?"0":s
};

126.汉罗塔问题

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vtiEmBvs-1634807680234)(算法题练习.assets/image-20211020160631990.png)]

/**
 * @param {number[]} A
 * @param {number[]} B
 * @param {number[]} C
 * @return {void} Do not return anything, modify C in-place instead.
 */
var hanota = function(A, B, C) {
let n=A.length
function move(m,a,b,c){
    if(m===1){
        c.push(a.pop())//当只有一个时直接加入到c中
    }else{
        move(m-1,a,c,b)//将a中的n-1个通过c移动到b
        c.push(a.pop())//将a中剩下的一个直接放到c
        move(m-1,b,a,c)//再把b上的n-1个通过a放到c

    }
}
move(n,A,B,C)
};

127.字符串集中分隔

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-laUqJfZD-1634807680234)(算法题练习.assets/image-20211020171425309.png)]

function tString(str) {
  let obj = {}
  for (let i = 0; i < str.length; i++) {
    if (!obj[str[i]]) {
      obj[str[i]] = str[i]
    }
    else {
      obj[str[i]] += str[i]
    }
  }
  let s = []
  for (let item in obj) {
    s.push(obj[item])
  }
  console.log(s.sort().toString());
}
tString("acbabcaab")

128.大数相加

let a = "9007199254740991"
let b = "123456789999999999"
function add(a, b) {
  let maxLength = Math.max(a.length, b.length)
  a = a.padStart(maxLength, 0)
  b = b.padStart(maxLength, 0)
  let t = 0, f = 0, s = ""
  for (let i = maxLength - 1; i >= 0; i--) {
    t = parseInt(a[i]) + parseInt(b[i]) + f
    f = Math.floor(t / 10)
    s = t % 10 + s
  }
  if (f === 1) {
    s = "1" + s
  }
  return s
}

console.log(add(a, b));
132463989254740990

封装axios

function axios(method="GET",url){
  return new Promise((resolve,reject)=>{
    var xhr=new XMLHttpRequest()
    xhr.open(method,url,true)
xhr.onreadystatechange()=function(){
if(xhr.readyState===4&&xhr.status==200){
resolve(xhr.responseText)
}
}
    xhr.send()

  })
}

你可能感兴趣的:(javascript,前端,vue.js)