[路飞]比较含退格的字符串/验证栈序列/有效的括号/删除最外层的括号

159 阅读6分钟

一.#### 844. 比较含退格的字符串 给定 s 和 t 两个字符串,当它们分别被输入到空白的文本编辑器后,如果两者相等,返回 true 。# 代表退格字符。

注意:如果对空文本输入退格字符,文本继续为空。
示例 1:
输入:s = "ab#c", t = "ad#c" 输出:true 解释:s 和 t 都会变成 "ac"。

示例 2:
输入:s = "ab##", t = "c#d#" 输出:true 解释:s 和 t 都会变成 ""。

示例 3:
输入:s = "a#c", t = "b" 输出:false 解释:s 会变成 "c",但 t 仍然是 "b"。

解题思路: 本题需解决的是两个数组需要将每个数组里的#和#前面的字符剔除,然后对比剩下的数组是否相等,解题思路是,定义两个空数组ss,tt,然后循环需要删选的数组,比如第一个数组循环时当内容不等于#时就将改内容插入到空数组里ss后面,如果是#就删除数组ss最后一位,然后循环对比ss,tt两个数组是否相等就好了,如果相等就返回true,反之返回false,代码如下:

var backspaceCompare = function(s, t) {
    定义两个空数组,保存删选出来的值
    let ss = [],tt = [];
    for(let i = 0; i < s.length; i ++) {
        //当等于#时删除ss数组最后一位
        if(s[i] === '#'){
            ss.pop();
        }else{
            //不等于#是想ss数组插入当前值保存
            ss.push(s[i])
        }
    }
    //跟上面同理
    for(let i = 0; i < t.length; i ++) {
        if(t[i] === '#'){
            tt.pop();
        }else{
            tt.push(t[i])
        }
    }
    //删选出来的内容如果长度不一样说明两个数组不相等直接返回fase
    if(ss.length !== tt.length) return false;
    //如果有一个数组为空说明两个数组经过删选都为空,也就是相等了
    if(ss.length === 0) return true;
    //循环对比两个数组舒服相等
    while(ss.length === tt.length && ss.length > 0){
        //如果相等就删掉
        if(ss[0] === tt[0]){
          ss.shift();
          tt.shift();
        } else{
          //如果不相等就说明不相等
             return false;
        }
    }
    //经过对比如果为空了说明相等
    return ss.length === 0;
};

二.#### 验证栈序列 给定 pushed 和 popped 两个序列,每个序列中的 值都不重复,只有当它们可能是在最初空栈上进行的推入 push 和弹出 pop 操作序列的结果时,返回 true;否则,返回 false 。

示例 1:
输入:pushed = [1,2,3,4,5], popped = [4,5,3,2,1] 输出:true 解释:我们可以按以下顺序执行: push(1), push(2), push(3), push(4), pop() -> 4, push(5), pop() -> 5, pop() -> 3, pop() -> 2, pop() -> 1

示例 2:
输入:pushed = [1,2,3,4,5], popped = [4,3,5,1,2] 输出:false 解释:1 不能在 2 之前弹出。  

解题思路* :本题是想验证栈的入栈和出栈是否正确,pushed是入栈顺序的数据,popped是出栈的顺序,本题的解题思路是现在pushed找到popped第一个出栈的数组,然后判断第二个出栈的数组内容是否是栈顶元素就是第一个删除的前一个数组,或者即将入栈的数字,也就是前一个出栈的后一位是否相等,如果都是相等的就是合法的,其实通俗点就是将pushed按照popped出栈是否正确,正确就是合法的,否则不合法,代码如下:

var validateStackSequences = function(pushed, popped) {
    //定义一个空数组保存操作入栈出栈
    let t1 = [];
    //循环入栈数组操作出栈操作,pushed此操作没有保存到t1就相当于出栈
    for(let i = 0; i < pushed.length; i ++){
        //找到出栈元素,没有加入t1相当如将改元素出栈,将已出栈元素去掉
        if(pushed[i] === popped[0]){
            popped.shift();
        }else{
            //不相等就保存没出栈元素,相当于入栈
            t1.push(pushed[i])
        }
        //获取已入栈数组长度
        let leng = t1.length ;
        //判断栈顶元素与与要出栈元素是否相等,如果相等就出栈
        while(t1[leng - 1] === popped[0] && leng > 0){
            t1.pop();
            popped.shift();     
            leng = t1.length ;   
        }
    }
    // 当t1和popped都为空就是合法的操作
    return t1.length === 0 && popped.length === 0;
};

三.#### 有效的括号 给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

左括号必须用相同类型的右括号闭合。 左括号必须以正确的顺序闭合。  

示例 1:

输入:s = "()" 输出:true 示例 2:

输入:s = "()[]{}" 输出:true 示例 3:

输入:s = "(]" 输出:false 示例 4:

输入:s = "([)]" 输出:false 示例 5:

输入:s = "{[]}" 输出:true  

提示:

1 <= s.length <= 104 s 仅由括号 '()[]{}' 组成

解题思路:本题解题思路还是栈的操作,先入先出,定义一个空数组就是当时左括号的时候奖盖元素保存到数组,当时右括号的时候先判断栈顶元素是否与当前元素是一对括号,如果是就是合法然后进行出栈操作,不是就是不合法,代码如下:

var isValid = function(s) {
    //定义一个空数组进行栈的操作
    let ss = [];
    for(let i = 0; i < s.length; i ++){
        //全局获取栈的长度
        let leng = ss.length;
        //匹配一对括号
        let type = {')':'(',']':'[','}':'{'}
        switch(s[i]) {
            case '(' :
            case '[' :
            case '{' : 
                 //当时左括号的时候入栈
                 ss.push(s[i]);
                 break;
             case ')':
             case ']':
             case '}':
                 //判断栈是否是空,如果时空或者栈顶元素与当前元素不能组成一对括号就是不合法的括号
                 if(leng < 1 || ss[leng -1] !== type[s[i]]) return false;
                 //判断是合法括号后出栈
                 ss.pop();
                 break;
        }
    }
    //当ss为空就说明是合法括号
    return ss.length === 0;
};  

四.#### 删除最外层的括号 有效括号字符串为空 ""、"(" + A + ")" 或 A + B ,其中 A 和 B 都是有效的括号字符串,+ 代表字符串的连接。

例如,"","()","(())()" 和 "(()(()))" 都是有效的括号字符串。 如果有效字符串 s 非空,且不存在将其拆分为 s = A + B 的方法,我们称其为原语(primitive),其中 A 和 B 都是非空有效括号字符串。

给出一个非空有效字符串 s,考虑将其进行原语化分解,使得:s = P_1 + P_2 + ... + P_k,其中 P_i 是有效括号字符串原语。

对 s 进行原语化分解,删除分解中每个原语字符串的最外层括号,返回 s 。

 

示例 1:

输入:s = "(()())(())" 输出:"()()()" 解释: 输入字符串为 "(()())(())",原语化分解得到 "(()())" + "(())", 删除每个部分中的最外层括号后得到 "()()" + "()" = "()()()"。 示例 2:

输入:s = "(()())(())(()(()))" 输出:"()()()()(())" 解释: 输入字符串为 "(()())(())(()(()))",原语化分解得到 "(()())" + "(())" + "(()(()))", 删除每个部分中的最外层括号后得到 "()()" + "()" + "()(())" = "()()()()(())"。 示例 3:

输入:s = "()()" 输出:"" 解释: 输入字符串为 "()()",原语化分解得到 "()" + "()", 删除每个部分中的最外层括号后得到 "" + "" = ""。

解题思路: 本题是需要把所有最外层括号去掉,本题解题思路是循环数组,定义一个变量默认为0当是左括号的时候就加一,当时右括号的时候就减一,当变量等于0此时就找到了第一个最大括号,这个时候可以定义一个变量循环这个最大括号除了最外一层不加,其他都接入变量,这样就把第一个最大括号外层去掉了,后面依次这样进行就可以把所有外层括号去掉,定一个变量j是第二个大括号的其实位置,代码如下:

var removeOuterParentheses = function(s) {
    //定义一个变量保存去掉外层的括号
    let sun = '';
    // 定义一个计算器,当等于0就是找到了第一个最大括号的最右边
    let index = 0;
    for(let i = 0, j = 0; i < s.length; i ++){
        //当时左括号index就加一
        if(s[i] === '('){
            index ++;
        }else{
            //右括号减一
            index --;
        }
        //判断index是否等于0,等于0,i就是第一个最大括号右边位置,
        if(index === 0){
            //将第一个最大括号进行循环除了第一位和最后一位不要,拼接到sun
            for(let a = j + 1; a < i; a ++){
                sun += s[a]
            }
            //下一个最大括号的其实位置
            j = i + 1;
        }
    }
    //sun就是所有去掉最外层括号的集合
    return sun;
};