【JavaScript算法】最长公共前缀 + 有效的括号

在这里插入图片描述

【1】LeetCode14. 最长公共前缀

编写一个函数来查找字符串数组中的最长公共前缀。

如果不存在公共前缀,返回空字符串 “”。

示例 1:

输入: [“flower”,“flow”,“flight”]
输出: “fl” 示例 2:

输入: [“dog”,“racecar”,“car”]
输出: “”
解释: 输入不存在公共前缀。

说明:

所有输入只包含小写字母 a-z 。

链接:https://leetcode-cn.com/problems/longest-common-prefix

1.1按顺序比较得到公共前缀

首先初始化前缀为第一个数组字符串,接下来就利用这个前缀字符串和下一个个字符串进行比较得到新的公共前缀,如此迭代n-1次最后得到的前缀就是最长公共前缀,例如

[“abcde”,“abcffr”,“abceef”]
初始化 s=“abcde”,与"abcffr"结合得前缀"abc"
接下来“abc”再与"abceef"结合得“abc”,结束

var longestCommonPrefix = function(strs) {

	var prefix=strs[0];//初始化前缀
    
    var get_prefix = function(a,b){
    	let result = []
    	let len = a.length>b.length?b.length:a.length

    	for(let i=0;i<len;i++){
    		if(a[i]==b[i]){
    			result.push(a[i])
    		}else{
    			return result[0]?result.join(""):""
    		}
    	}

    	return result[0]?result.join(""):""
    }


    for(let i=1;i<strs.length;i++){
    	prefix=get_prefix(prefix,strs[i]);
    }


    return prefix?prefix:""


};

在这里插入图片描述

1.2 使用按列扫描判断的方法

看到前面的时间和空间效率不算很高,我得考虑使用新的算法。以前做机器学习作业的时候曾经按列处理过数据,但是js的二维数组明显没有那样python矩阵处理好用。

也是采用迭代更新前缀的方式
将其看成二维数组,按列(红色部分)全部比较是否相等,若是然后将其字符增加到前缀里
在这里插入图片描述
具体怎么一次性比较?采用递归的方式,传入参数(行数,列下标)
递归函数中的递归方程

F(n,i) = F(n-1,i) x (strs[n]==strs[n-1]) 
 F(0,i) = 1 //只有一行的时候直接就是比较相等的意思

将其用作循环的判断条件

//列判断,出现某一列中不全相等就终止
while(fun(n,i)){
  prefix=prefix+strs[0][i]
  i++
}

但是这么写递推方程会有一个BUG!害查了好久!!
就是当输入为完全相同的字符串组时,会导致死循环
例如[“ce”,“ce”],比较完ce后后面的比较都是undefined==undefined(true),就会一直循环下去直至越界,所以要给递归函数加一个判断条件:

F(n,i) = F(n-1,i) x (strs[n]==strs[n-1]) x (strs[n][i]!=undefined)

最后代码如下:

var longestCommonPrefix = function(strs) {

    if(!strs[0])return ""
    if(strs.length==1)return strs[0]

	var prefix="";//初始化前缀
    var len=strs.length
    var n=strs.length-1
    var i=0//列数
    //递归函数调用的全局变量是strs,i(会变化)
    var fun = function(n,i){
    if(n>0){
    	//console.log("strs["+n+"]["+ i +"] = "+strs[n][i])
    	return fun(n-1,i)*Number(strs[n][i]==strs[n-1][i]&&strs[n][i]!=undefined)
    }else{
    	return 1
    }
}//fun

    //列判断,出现不对就终止
    while(fun(n,i)){
      prefix=prefix+strs[0][i]
      i++
    }

    return prefix


};

在这里插入图片描述

【2】LeetCode20. 有效的括号

给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串,判断字符串是否有效。

有效字符串需满足:

左括号必须用相同类型的右括号闭合。 左括号必须以正确的顺序闭合。 注意空字符串可被认为是有效字符串。

不用说,肯定是利用到栈这个数据机构的

左括号直接入栈
右括号进行栈顶匹配,若是匹配则左右括号两个一起出栈
期间若左右不匹配的情况出现则返回false
最后栈空则判断是true

怎么让 }知道他的配偶是 { ?(左右括号匹配识别)
利用map对象,如下:

var isValid = function(s) {
    let map=new Map()

    map.set('(',0)
    map.set('[',1)
    map.set('{',2)

    map.set(')',0)
    map.set(']',1)
    map.set('}',2)

    let s_arr=s.split('')
    let stack=[]
    for(let i=0;i<s.length;i++){
        if(s_arr[i]=='('||s_arr[i]=='['||s_arr[i]=='{'){
            //如果是左闭合,入栈
            stack.push(s_arr[i])
        }else{
            //如果是右闭合
            if(map.get(s_arr[i])!=map.get(stack[stack.length-1])){
                //判断不一致
                return false
            }else{
                //完整闭合,出栈
                stack.pop()
            }
        }
    }

    if(stack.length==0)return true
    else return false
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值