JS算法之栈

leetcode155:最小栈

var MinStack = function() {
    this.stack = []
    this.min_stack = [Number.MAX_VALUE]
};

/** 
 * @param {number} x
 * @return {void}
 */
MinStack.prototype.push = function(x) {
    this.stack.push(x)
    if(x > this.min_stack[this.min_stack.length-1]) {
        this.min_stack.push(this.min_stack[this.min_stack.length-1])
    }else {
        this.min_stack.push(x)
    }
};

/**
 * @return {void}
 */
MinStack.prototype.pop = function() {
    this.stack.pop();
    this.min_stack.pop()
};

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

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

leetcode20:有效的括号

var isValid = function(s) {
    var a = [];
    var b = {')':'(','}':'{',']':'['};
    for(let i = 0 ; i < s.length ; i++){
        if(s[i] == '(' || s[i] == '{' || s[i] == '['){
            a.push(s[i]);
        }else {
            if(b[s[i]] == a[a.length-1]){
                a.pop()
            }else{
                return false
            }
        }
    }
    if(a.length == 0) return true;
    else return false;
};

b属性也可以用ES6的新增数据结构:map

const map = new Map([    //可初始化数据,两两一对,任意类型
    [1,2],
    ['2',3]
])

const obj = {p: 'Hello World'};

map.set(obj, 'OK')   //设置成员的key和value
map.get(obj) // "OK"	//获得属性的值
map.has(obj) // true	//判断成员是否存在
map.delete(obj) // true		//删除成员
map.clear(obj) // false		//清空所有	

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

var removeDuplicates = function(S) {
    var a = '';
    for(let i = 0; i < S.length; i++) {
        if(S[i] != S[i+1]){
            a+=S[i];
        }else{
            i++;
        }
    }  
    if(a.length == S.length){
        return a
    }else{
        return removeDuplicates(a)
    }
};

一开始没想清用栈怎么写,感觉用栈的话只能删除一层相邻重复项,再合并的重复项没法删掉。但其实不然,用栈的话,可以一层一层的抵消。

var removeDuplicates = function(S) {
    var stack = [];
    for(let i = 0; i < S.length; i++) {
        if(S[i] != stack[stack.length - 1]){
            stack.push(S[i]);
        }else{
            stack.pop();
        }
    }
    return stack.join('')
};

leetcode1209:删除字符串中的所有相邻重复项(中等)

一开始想的是跟简单题一样,多一个for循环判断重复个数就可以了,但结果超时了。

var removeDuplicates = function(s, k) {
    var stack = [];
    for(let i = 0; i < s.length; i++){
        if(s[i] == stack[stack.length-1]){
            var f = 0;
            for(let j = 0; j < k-1 ;j++){
                if(s[i] == stack[stack.length-1-j]){
                    f++;
                }
            }
            if(f == k-1){
                for(let j = 0; j < k-1; j++) {
                    stack.pop();
                }
            }else{
                stack.push(s[i])
            }
        }
        else{
            stack.push(s[i])
        }   
    }
    return stack.join('')
};

改良版:往栈里压入对象,保存重复个数,实现O(n)。

利用了字符串的repeat(count)方法。var a = str.repeat(count)实现将str复制count次给a

var removeDuplicates = function(s, k) {
    var stack = [];
    for(let i = 0; i < s.length; i++) {
        if(stack.length && s[i] == stack[stack.length-1].val){
            stack[stack.length-1].count++;
            if(stack[stack.length-1].count == k){
                stack.pop();
            }
        }else{
            stack.push({val:s[i],count:1});
        }
    }
    return stack.reduce((pre,now) => {
        return pre + now.val.repeat(now.count);
    },'')
};

面试真题:删除字符串中出现次数 >= 2 次的相邻字符

这个题更进一步,不限制固定的重复次数

var removeDuplicates = function(s) {
  var stack = [];
  for(let i = 0; i < s.length; i++) {
    if(stack.length && s[i] == stack[stack.length-1].val) {
      stack[stack.length-1].count++;
    }
    else{
        if(stack.length && stack[stack.length-1].count >= 2){
          stack.pop();
        }
        if(stack.length && s[i] == stack[stack.length-1].val){
          stack[stack.length-1].count++;
        }else{
          stack.push({val:s[i],count:1})
        }
      }
  }
  return stack.reduce((pre,now) => {
      return pre + now.val
  },'')
}
console.log(removeDuplicates('abbbacca'));
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值