[路飞]_js算法实现:有效的括号 合并链表 计数排序 二叉树前序遍历

337 阅读2分钟

用栈实现字符串匹配(有效的括号)

问题: 给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。 有效字符串需满足: 左括号必须用相同类型的右括号闭合。 左括号必须以正确的顺序闭合。

思路: 利用栈的数据结构,将左侧括号依次入栈,遇到右括号,则看栈尾是否匹配,是的话,取出栈尾。否则判定为输入不合理。(只用到数组的push及pop方法就能实现栈的后入先出,后期我们可以一起实现栈的常用方法封装到一个构造函数中~)

function judgeValidBracket(str){
let bracket={
    "{":"}",
    "[":"]",
    "(":")"
}
let arr=str.split('');
let bracketArr=[];//临时栈数组
for(let i=0;i<arr.length;i++){
    for(let key of bracket){//遍历属性值
        if(arr[i]==key){//左括号入栈
            bracketArr.push(arr[i])
        }
        // 这里限定了只有指定字符串,所以不需要做额外非法字符串判断,直接进else
        else if(arr[i]!=bracket[bracketArr.pop()]){
            return false
        }
    }
}
return true;
}

测试:
let str="{[]}";//参数
judgeValidBracket(str)//true

合并两个有序链表

问题: 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

参数: l1(链表1的头节点), l2(链表2的头节点)

class Node{
 constructor(val){
 this.val=val;
 this.next=null
 }
}

解法一:

思路: 创建新的链表,依次循环两个链表,把较小的放进新链表,直到两个链表循环结束。

function concatLists(l1,l2){
let temp=new Node();//合并后的链表(虚拟头节点)
let cur=temp;//合并后的链表指向
while(l1!=null&&l2!=null){
  if(l1.val>l2.val){
    cur.next=l2;
    l2=l2.next;
  }else{
    cur.next=l1;
    l1=l1.next;
  }
  cur=cur.next;
 }
}
// 此时可能剩余一个节点未参与比较
cur.next=l1?l2:l1;
return temp.next;

解法二:

思路: 采用递归的方法,直接改变原来链表的指向,返回头节点小的链表。

// 递归 返回比较小的,作为下一个节点
function getCurNode(l1,l2){
  if(l1==null)return l2;
  if(l2==null)return l1;
  if(l1.val>l2.val){
    l2.next=getCurNode(l1,l2.next);
    return l2
  }else{
    l1.next=getCurNode(l1.next,l2);
    return l1
  }

计数排序

(针对各项数大小有限,会牺牲较大的的空间)

算法思想: 把数字n放入新数组的第n个桶,填充目标数组,将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1。

实现:

function countSort(arr) {
    let maxValue=0;
   // 先找到最大值
    for(let i=0;i<arr.length;i++){
        maxValue=maxValue<arr[i]?arr[i]:maxValue;
    }
    //完善桶边数
    let bucketArr =new Array(maxValue + 1);
    let sortIndex = 0;
 //木桶边位置是值,高度值(每个位置上的值)是有多少个同样的值
    for (let i = 0,len=arr.length; i < len; i++) {
        if (!bucket[arr[i]]) {
            bucket[arr[i]] = 0;
        }
        bucket[arr[i]]++;
    }
    //从桶里取值 排序
    for (let j = 0,len=bucketArr.length; j < len; j++) {
        while(bucket[j] > 0) {
            arr[sortedIndex++] = j;
            bucket[j]--;
        }
    }
    return arr;
}

二叉树前序遍历

//创建二叉树
      class Node{
           constructor(data,left,right){
               this.data = data;
           this.left = left;
           this.right = right;
           }
           show(){
               return this.data;
           }
       }
       class BST{
           constructor(){
               this.root = null;
           }
          //生成二叉树
          insert(data){
           var node = new Node(data,null,null);
           if(this.root == null){
               this.root = node;
           }else{
               var current = this.root;
               var parent;
               while(true){
                   parent = current;
                   if(data < current.data){
                       current = current.left;
                       if(current == null){
                           parent.left = node;
                           break;
                       }
                   }else{
                       current = current.right;
                       if(current == null){
                           parent.right = node;
                           break;
                       }
                   }
               }
           }
       }
       //先序遍历
       preOrder(node){
           if(node){
               console.log(node.show() + " ");
               this.perOrder(node.left);
               this.perOrder(node.right);
           }
       }
       }
       
       测试:
       var bst  = new BST();
       var nums = [];//参数
       for(var i = 0;i < nums.length;i ++){
           bst.insert(nums[i]);
       }
       bst.perOrder(bst.root);