JavaScript-牛客网-剑指offer(21-30)题解

本文介绍了使用JavaScript解决剑指Offer中第21至30题的方法,包括栈的压入弹出序列、二叉树的打印、二叉搜索树的后序遍历、和为特定值的路径、复杂链表复制等算法问题。通过简洁的代码示例阐述解题思路。
摘要由CSDN通过智能技术生成

剑指offer第21-30题解答(javascript)

本文章尽量用简洁的代码去完成题目要求,话不多说,上代码。

21.栈的压入,弹出序列

题目描述:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)

function IsPopOrder(pushV, popV){
    // write code here
    let stack=[];
    for(let i=0,j=0;i<pushV.length;i++){
        stack.push(pushV[i]);
        while(popV[j]==stack[stack.length-1]&&stack.length){
              stack.pop();
              j++;
        }
    }
    return stack.length==0;
}

22.从上往下打印二叉树

题目描述:从上往下打印出二叉树的每个节点,同层节点从左至右打印。

function PrintFromTopToBottom(root){
    // write code here
    let arr=[];
    let res=[];
    if(root){arr.push(root)}
    while(arr.length){
        let node=arr.shift();
        if(node.left) arr.push(node.left);
        if(node.right) arr.push(node.right);
        res.push(node.val);
    }
    return res
}

23.二叉搜索树的后序遍历序列

题目描述:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。

function VerifySquenceOfBST(sequence){
    // write code here
    if(!sequence.length){return false;}
    let s = sequence.length,c = 0;
    while(--s){
        while(sequence[c++] < sequence[s]);//s是根节点,前面的数小于s
        while(sequence[c++] > sequence[s]);//s是根节点,后面的数大于s
        if(c < s){return false;}
        c = 0;
    }
    return true;
}

24.二叉树中和为某一值的路径

题目描述:输入一颗二叉树的根节点和一个整数,按字典序打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。

let r,p
function FindPath(root, expectNumber){
    // write code here
    r = []
    p = []
    if(!root){return r};
    cal(root,expectNumber)
    return p
}
function cal(root,exp){
    r.push(root.val);
    if(root.val == exp && !root.left&& !root.right){
        p.push(r.slice())
    }else{
        if(root.left) cal(root.left,exp - root.val);
        if(root.right) cal(root.right,exp - root.val);
    }
    r.pop()
} 

25.复杂链表的复制

题目描述:输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针random指向一个随机节点),请对此链表进行深拷贝,并返回拷贝后的头结点。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)

function Clone(pHead){
    // write code here
    if(!pHead) return null;
    let h = new RandomListNode(pHead.label);
    h.random = pHead.random;
    h.next = Clone(pHead.next);
    return h
}

26.二叉搜索树与双向链表

题目描述:输入一个整数,输出该数32位二进制表示中1的个数。其中负数用补码表示.

function Clone(pHead){
    // write code here
    if(!pHead) return null;
    let h = new RandomListNode(pHead.label);
    h.random = pHead.random;
    h.next = Clone(pHead.next);
    return h
}

27.字符串的排列

题目描述:输入一个整数,输出该数32位二进制表示中1的个数。其中负数用补码表示.

function Permutation(str){
    // write code here
    let res=[]
    if(str.length<=1){return str}
    let flag={}
    for(let i=0;i<str.length;i++){
        let s=str[i]
        if(!flag[s]){
            let newstr=str.slice(0,i)+str.slice(i+1,str.length)
            let l=Permutation(newstr)
            for(let j=0;j<l.length;j++){
                let temp=s+l[j]
                res.push(temp)
            }
             flag[s]=true
        }
    }
    return res
}

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

题目描述:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。

function MoreThanHalfNum_Solution(numbers){
    // write code here
    if (!numbers.length) return 0;
    let arr = [];
    for(let i=0;i<numbers.length;i++) {
        if (!arr[numbers[i]]) {
            arr[numbers[i]] = 1;
        }else {
            arr[numbers[i]]++;
        }
    }
    for(let i=0;i<numbers.length;i++) {
        if (arr[numbers[i]] > numbers.length/2) {
            return numbers[i];
        }
    }
    return 0;
}

29.最小的K个数

题目描述:输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4。

function GetLeastNumbers_Solution(input, k){
    // write code here
    let arr=[];
    if(input.length<k){
        return arr
    }
    input.sort(function(a,b){return a-b});
    for(let i=0;i<k;i++){
        arr.push(input[i])
    }
    return arr
}

30.连续子数组的最大和

题目描述:HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住?(子向量的长度至少是1)

function FindGreatestSumOfSubArray(array){
    // write code here
    if(array.length==1){
        return array[0]
    }
    for(let i =1;i < array.length;i++){
        if(array[i-1]>0){
            array[i] = array[i]+array[i-1]
        }
    }
    return Math.max(...array)
}

让心存江湖的人,继续江湖的梦吧。
未完待续,Loading…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值