当前位置: 首页 > news >正文

字符串操作栈和队列

反转字符串II

在这里插入图片描述

/**
 * @param {string} s
 * @param {number} k
 * @return {string}
 */
var reverseStr = function(s, k) {
    // //字符串=》字符数组
    // let sArr=s.split('');
    // let length=s.length;
    // //每计数2*k for!!!
    // for(let i=0;i<length;i+=2*k){
    //     let left=i;
    //     //right指向要反转的最后字符们不要mid!
    //     //三元表达式,判断i+k-1右边的指针是否超过字符长度(2k与2k>=k),没超过就是交换前k
    //     //超过标识字符小于k,就全交换剩下的字符
    //     let right=(i+k-1)>=length?length-1:i+k-1;
    //     while(left<right){
    //         [sArr[left],sArr[right]]=[sArr[right],sArr[left]];
    //         left++;
    //         right--;
    //     }
    // }

    const reverse=(arr,left,right)=>{
        while(left<right){
            [arr[left],arr[right]]=[arr[right],arr[left]];
            left++;right--;
        }
    }

    //核心是模拟,无需讨论情况,每次跳2k,并判断(当前位置+k)是否越界

    let arr=s.split('');
    //2*k不是2k
    for(let i=0;i<s.length;i+=2*k){
        //如果剩余元素大于k/有2k个元素
        if(i+k-1<s.length){
            reverse(arr,i,i+k-1);
        }else{
            reverse(arr,i,s.length);
        }
    }
    return arr.join(''); 
};

翻转字符串中的单词

在这里插入图片描述

/**
 * @param {string} s
 * @return {string}
 */
var reverseWords = function(s) {

   /**
 * @param {string} s
 * @return {string}
 */
var reverseWords = function(s) {


    
    //推荐
    let wordArr=s.split(" ");
    let filtered=wordArr.filter(item=>item!=="");
    let length=filtered.length;
    let right=length-1;
    for(let left=0;left<length;left++){
        if(left>=right){
            break;
        }
        [filtered[left],filtered[right]]=[filtered[right],filtered[left]];
        right--;
    }
    return filtered.join(" ");



    // //字符数组
    // let charArr=Array.from(s);

    //  var removeBlank=(arr)=>{
    //     let left=0;
    //     for(let right=0;right<arr.length;right++){
    //         //为最前面有空格或连续空格
    //         if(arr[right]===" "&&(right===0||arr[right-1]===" "))continue;
    //         else{
    //             arr[left]=arr[right];
    //             left++;
    //         }
    //     }
    //     //考虑到移除尾部单个空格
    //     //因为执行赋值后有left++了,所以此处要再减1
    //     arr.length=arr[left-1]===" "?left-1:left;//此处求的是长度,slow指针索引,从0开始
    // }

    // //移除空格
    // removeBlank(charArr);

    // // //思路:去除空格,去除对于空格(双指针)
    // // //反转全部->反转每个单词
    // var reverse=(arr,left,right)=>{
    //     while(left<right){
    //         [arr[left],arr[right]]=[arr[right],arr[left]];
    //         left++;
    //         right--;
    //     }
    // }
    // // //反转全部
    // reverse(charArr,0,charArr.length-1);
    
    // // //反转每个单词
    // // 没遇到空格就是一个新单词或者到结尾
    // let left=0;
    // let right=0;
    //  //right===charArr.length是right-1才是最后一位
    // for(;right<=charArr.length;right++ ){
    //     //right===charArr.length是right-1才是最后一位
    //     if((charArr[right]===" ")|| (right===charArr.length)){
    //         reverse(charArr,left,right-1);
    //         left=right+1;
    //     }
    // }

    //return charArr.join(''); 
}
}

KMP经典应用

在这里插入图片描述

next初始化-> 前后缀不相同(回退,next数组)->前后缀相同->j加入next数组
初始化,获取next数组->前后缀不相同(回退,next数组)->前后缀相同->到末尾

/**
 * @param {string} haystack
 * @param {string} needle
 * @return {number}
 */
var strStr = function(haystack, needle) {

    if(needle.length===0)return 0;
    let next=getNext(needle);
    let j=0;
        for(let i=0;i<haystack.length;i++){
        //字符匹配到不同的,回溯跳!!!while
        while(j>0 && haystack[i]!==needle[j]){
            j=next[j-1];//写成need[j-1],excuse me?
        }
        //相等时,继续往下匹配
        if(haystack[i]===needle[j]){
            j++;
        }
        //匹配成功,i此时仍指向最后一字符
        //气死,length写出lenth,死都找不到那出错了
        if(j===needle.length){
            return i-needle.length+1;
        }
    }
    //未找到
    return -1;

};

var getNext=function(needle){
    //初始化
    let next=[];
    let j=0;
    next.push(j);
    //双指针!
    for(let i=1;i<needle.length;i++){
        //前后缀不同,循环回溯
        while(j>0&&needle[i]!==needle[j]){
            j=next[j-1];
        }
        if(needle[i]===needle[j]){
            j++;
        }
        next.push(j);
    }
    //记得返回出去!!!
    return next;
}

重复的字子字符串(能用KMP!前后缀)

在这里插入图片描述

结论:保证next大于0,即有最长前后缀,子串中除去最长前后缀其他部分为最小重复字符串
除去这个最长相等的前缀和后缀剩下的部分(即重复的子串)是否能整除整个字符串的长度。如果可以整除,说明 s 是由这个更小的字符串重复构成的。

/**
 * @param {string} s
 * @return {boolean}
 */
var repeatedSubstringPattern = function(s) {
    let next=getNext(s);
    //保证next大于0,即有最长前后缀,子串中除去最长前后缀的其他部分为最小重复字符串
    //next[next.length-1] 表示整个字符串 s 的最长相等的前缀和后缀的长度。
    //s.length % (s.length - next[next.length-1]) === 0 用于判断,除去这个最长相等的前缀和后缀
    //剩下的部分(即重复的子串)是否能整除整个字符串的长度。如果可以整除,说明 s 是由这个更小的字符串重复构成的。
    if(next[next.length-1]>0&&s.length%(s.length-next[next.length-1])===0)return true;
    return false;
};
var getNext=function(s){
    //初始化
    let j=0;
    let next=[];
    next.push(j);
    for(let i=1;i<s.length;i++){
        //前后缀不相同
        while(j>0&&s[i]!==s[j]){
            //回溯
            j=next[j-1];
        }
        //前后缀相同时
        if(s[i]===s[j]) j++;
        //更新next数组
        next.push(j);
    }
    return next;
}

有效的括号

在这里插入图片描述

/**
 * @param {string} s
 * @return {boolean}
 */
var isValid = function(s) {
    // let stack=[];

    // for(let i=0;i<s.length;i++){
    //     let cur=s[i];
    //     switch(cur){
    //         case "{":
    //             stack.push("}");
    //             break;
    //         case "(":
    //             stack.push(")");
    //             break;
    //         case "[":
    //             stack.push("]");
    //             break;
    //         default:
    //             let flag=stack.pop()===cur;
    //             if(!flag)return false;
    //     }
    // }
    // return stack.length===0;

    const stack = [];
    //键值对
    let  obj1  = {
            "(":")",
            "{":"}",
            "[":"]"
        };
    for(const x of s) {
        if(x in obj1) {
            //遇到左括号将对应右括号加入栈
            stack.push(obj1[x]);
            //跳出本次循环
            continue;
        };
        //遇到右括号从栈中弹出数据,若不同就返回false
        if(stack.pop() !== x) return false;
    }
    //若还剩数据也不行!!!
    return !stack.length;

};

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

在这里插入图片描述

/**
 * @param {string} s
 * @return {string}
 */
var removeDuplicates = function(s) {
    //初始化空栈
    let stack=[];
    for(let i=0;i<s.length;i++){
        let cur=s[i];
        //判断栈是否为空
        if(stack.length>0){
            //不为空,将当前数据和栈顶数据比较
            let top=stack[stack.length-1]
            if(top===cur){
                //相同就弹出
                stack.pop();
            }else{
                //不相同就将此数据继续加入栈中
                stack.push(cur);
            }
        }else{
            //当栈中没数据就加入
            stack.push(cur);
        }
    }
    return stack.join("");


};

逆波兰表达式求值

/**
 * @param {string[]} tokens
 * @return {number}
 */
var evalRPN = function(tokens) {

    //思路:初始化一个栈,遇到数字就将数字压入栈中
    //遇到符号就从栈中弹出两个数字,弹出的数字的顺序matters!!!
    //然后再将结果压入栈,直至处理完成
    const stack = [];
    for (const token of tokens) {
        if (isNaN(Number(token))) { // 非数字
            const n2 = stack.pop(); // 出栈两个数字
            const n1 = stack.pop();
            switch (token) { // 判断运算符类型,算出新数入栈
                case "+":
                    stack.push(n1 + n2);
                    break;
                case "-":
                    stack.push(n1 - n2);
                    break;
                case "*":
                    stack.push(n1 * n2);
                    break;
                case "/":
                    stack.push(n1 / n2 | 0);
                    break;
            }
        } else { // 数字
            stack.push(Number(token));
        }
    }
    return stack[0]; // 因没有遇到运算符而待在栈中的结果
};

滑动窗口最大值★★★

在这里插入图片描述

前K个高频元素★★

在这里插入图片描述

大小堆原理详解

相关文章:

  • MES生产工单管理系统,Java+Vue,含源码与文档,实现生产工单全流程管理,提升制造执行效率与精准度
  • C++使用Qt Charts可视化大规模点集
  • matlab中排序函数sortrows的用法
  • 快速入手-前后端分离Python权限系统 基于Django5+DRF+Vue3.2+Element Plus+Jwt
  • SQL注入流量分析
  • 【算法】二分查找
  • 单片机实现触摸按钮执行自定义任务组件
  • IntelliJ IDEA下开发FPGA——FPGA开发体验提升__下
  • 量子计算模拟中的GPU加速:从量子门操作到Shor算法实现
  • 嵌入式硬件实战基础篇(三)-四层板PCB设计-步进电机驱动(TMC2208/TMC2209)
  • 双周报Vol.69: C FFI 支持 borrow、新增.mbt.md测试与调试、WASM 后端支持extern type..
  • Python----计算机视觉处理(Opencv:道路检测完整版:透视变换,提取车道线,车道线拟合,车道线显示,)
  • 解决:Fontconfig head is null, check your fonts or fonts configurat
  • Java设计模式之外观、享元、组合模式《三国争霸:模式风云录》
  • Spring MVC 框架 的核心概念、组件关系及流程的详细说明,并附表格总结
  • 【探商宝】 Llama 4--技术突破与争议并存的开源多模态
  • 【机器学习】ROC 曲线与 PR 曲线
  • Python 3.13.2 安装教程(附安装包)轻松开启编程之旅
  • c# 系列pdf转图片 各种处理2--net3.1到net8
  • OpenCV鼠标事件
  • 大学2025丨苏大教授王尧:文科最大的危机是阐释世界的能力弱化
  • 荣盛发展:新增未支付债务11.05亿元
  • 技术派|威胁F-35、击落“死神”,胡塞武装防空战力如何?
  • 外企聊营商|武田制药:知识产权保护助创新药研发
  • 贝壳一季度收入增长42%:二手房市场活跃度维持在高位
  • 《大风杀》导演张琪:为了不算计观众,拍了部不讨好的警匪片