持续更新ing!

本博客题目来源于牛客网上的企业高频面试题,对应到leetcode中的题目序号。

 

20 有效括号

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

有效字符串需满足:

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

示例 1:

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

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

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

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

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

提示:

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

 

思路:使用栈来存放右括号,遍历字符串     步骤如下:

1.创建一个Map,把括号匹配放进去

2.创建一个Stack(array) ,用for循环遍历字符串,对于每一个字符,如果map里有这个key,那说明它是个左括号,从map里取得相应的右括号(为什么?),把它push进stack里,否则的话,它就是右括号,需要pop出栈顶字符然后看它是否等于当前的字符,如果不相符,则返回false

3.循环结束后,如果stack不为空,说明还剩一些左括号没有被闭合,返回false.否则返回true

var isValid = function(s) {
        // 创建括号配对关系
        const mappings = new Map();
        mappings.set('(',')');
        mappings.set('[',']');
        mappings.set('{','}');

        const stack = [];
        for(let i=0;i<s.length;i++){
            // 若当前字符对应mappings里的左括号,则push进去对应的右括号
            if(mappings.has(s[i])){
                stack.push(mappings.get(s[i]));
            // 若为右括号,则pop出来并与当前字符比较,若相等就什么都不做,不相等返回false
            }else{
                if(stack.pop()!=s[i]){
                    return false;
                }
            }
        }

        // 遍历完之后若stack中不为空,说明有的左括号没有被闭合,返回false
        if(stack.length!==0){
            return false;
        }
        // 若不为空,返回true
        return true;
    };

 

 

415. 字符串相加(大数加法)

给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和。

 

提示:

num1 和num2 的长度都小于 5100
num1 和num2 都只包含数字 0-9
num1 和num2 都不包含任何前导零
你不能使用任何內建 BigInteger 库, 也不能直接将输入的字符串转换为整数形式

 

思路: 使用双指针来模拟人工计算,步骤如下:

1. 创建指针 i 指向 nums1 末位数字,j 指向 nums2末位数字。
2. i, j 数字相加,用进位就用 carry 来记录进位值,无则为 0。
3. 若产生进位,则当前数字为 (i+j)%10 的值。
4. 若遍历过程中,nums1 或 nums2 当前已无数字,则用 0 补位来计算。

var addStrings = function(num1, num2) {
    let i=num1.length-1,
        j=num2.length-1,
        carry=0,
        ans=[];
    while(i>=0 || j>=0 || carry!==0){
        let c1 = i>=0?num1.charAt(i)-'0':0,
            c2 = j>=0?num2.charAt(j)-'0':0;
        let sum = c1+c2+carry;
        ans.push(sum%10);
        carry=Math.floor(sum/10);
        i--;
        j--;
    }
    return ans.reverse().join('');
};

 

 

344. 反转字符串

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。

不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。

你可以假设数组中的所有字符都是 ASCII 码表中的可打印字符。

 

示例 1:

输入:["h","e","l","l","o"]
输出:["o","l","l","e","h"]
示例 2:

输入:["H","a","n","n","a","h"]
输出:["h","a","n","n","a","H"]

 

思路:定义头尾指针,遍历交换两个指针指向的值

var reverseString = function(s){
    let i=0,j=s.length-1;
    while(i<j){
        let tmp = s[j];
        s[j]=s[i];
        s[i]=tep;
        i++;
        j--;
    }
    return s;
}

 

5. 最长回文子串

给你一个字符串 s,找到 s 中最长的回文子串。

 

示例 1:

输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。
示例 2:

输入:s = "cbbd"
输出:"bb"
示例 3:

输入:s = "a"
输出:"a"
示例 4:

输入:s = "ac"
输出:"a"
 

提示:

1 <= s.length <= 1000
s 仅由数字和英文字母(大写和/或小写)组成

 

思路步骤:

1.如果字符串小于2,直接返回字符串

2.定义两个变量,start存储当前找到的最大回文字符串的起始位置,另一个maxLength 记录字符串的长度(终止位置就是start+maxLength)

3.创建一个 helper function, 判断左边和右边是否越界,同时最左边的字符是否等于最右边的字符。如果三个条件都满足,则判断是否需要更新回文字符串的最大长度以及最大字符串的起始位置。然后将left--  ,right++,继续判断,直到不满足三个条件之一。

4. 遍历字符串,每个位置调用helper function两边,第一遍检查i-1,i+1   第二遍检查 i, i+1

 

var longestPalindrome = function(s) {
    if(s.length<2) return s;

    let start = 0;   // 存储最长子串的起始位置
    let maxLength = 1; // 考虑字符串为 ab 时, 最长回文子串长度为 1

    // 两种情况,可以提取出一个通用函数
    function expandAroundCenter(left,right){
        // 判断是否有越界、左右两边字符是否相等
        while(left>=0 && right<s.length && s[left]===s[right]){
            if(right-left+1>maxLength){
                maxLength = right-left+1;
                start = left;  
            }
            // 向两边扩散
            left--;
            right++;
        }
    }
    // 需要调用两种情况:  abba   abbba
    for(let i=0;i<s.length;i++){
        expandAroundCenter(i-1,i+1);
        expandAroundCenter(i,i+1);
    }
    return s.substring(start,start+maxLength);
};

 

posted on 2021-06-11 00:05  BillGates--  阅读(101)  评论(0)    收藏  举报