简单的3道算法题——多用小技巧

718 阅读1分钟

这是我参与更文挑战的第21天,活动详情查看:更文挑战

1.判断括号

  • 题目描述:
判断由"()[]{}"6种括号组成的字符串是否合法,即满足下面的条件:
1. 所有括号必须闭合
2. 左括号必须在正确的位置闭合
  • 题目解析

    1. 主要思想是利用栈推入左半边括号,然后判断右半边括号是否在字符串剩余部分出现。
    2. 用键值对的方式去判断是否包含左右括号。
function IsValid(string) {
  let str = string;
  let map = {
    '(': -1,
    ')': 1,
    '[': -2,
    ']': 2,
    '{': -3,
    '}': 3
  };

  let stack = [];
  let sum = 0;
  for(let i = 0; i < str.length; i++) {
    var temp = str.charAt(i);
    let stackLen = stack.length;
    if(map[temp] < 0) { // 只有左括号和左右括号都有
      stack.push(temp); // 推入括号
    } else if(stackLen > 0 && (map[stackLen - 1] !== -map[temp])) {
      stack.pop();
    }

    if(map[temp]) { // 只有右括号和没有括号
      sum += map[temp];
    }
  }

  if(stack.length === 0 && sum === 0) {
    return true;
  } else {
    return false;
  }
}

2.中间高两边低排序

  • 题目描述:
1,4,5,23,2,17,24,10000000。

按照中间高两边低进行排序,

最后的结果是 1,4,5,23,10000000,24,17,2
  • 题目解析:

    1. 从题目来看就是把数组一分为二,再把最大值放到中间。
    2. 其实还可以简单一些:就是一分为二之后,左边的从小到大,右边的从大到小。
var string = "1,4,5,23,2,17,24,10000000";
var num = string.split(',');
var len = num.length;
var left=[],right=[];
for(var i = 0; i<len; i++){
    if(i < len/2){
        left.unshift(num[i]);
    }else{
        right.push(num[i]);
    }
}
left.sort(function(a,b){ return a-b});
right.sort(function(a,b){ return b-a});

$("#sortval").html(left.concat(right).join(','));

数组排序用sort函数,string转数组用split就行了,最后将数组拼接起来,join转化为字符串。

3.摧毁数组

  • 算法描述:
实现一个摧毁(destroyer)函数,第一个参数是待摧毁的数组,其余的参数是待摧毁的值。
例子: destroyer([1, 2, 3, 1, 2, 3], 2, 3) 应该返回 [1, 1].
  • 解题思路:

    • 将数组中的数字和后面的参数进行一一匹配,不相等则返回,相等则不返回。
  • 实现方法:

    • 算法类似过滤因此可以使用filter函数,将数组中的数字过滤。
    • 使用arguments来进行参数的遍历。
function destroyer(arr) {
  // Remove all the values
  var arr_arg = arguments;
  for(var i = 1; i < arr_arg.length; i++){
    arr = arr.filter(function(val){
      return arr_arg[i] !== val;   
    });
    }
  return arr;
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);

用for循环将数组中的数字与参数进行匹配,除了第一个参数(为数组)。 以上是最基础的一种解法,其实一行就可以搞定。 利用reduce中的遍历省掉了for循环,具体方法如下。

function destroyer(arr) {
    // Remove all the values
    return [].slice.call(arguments).reduce(function (prev, next) {
        return prev.filter( e => e !== next);
    });
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);

[ ].slice.call(arguments)的意思和arguments.slice()的方法一样,但是arguments没有这种方法,所以用call方法调用。