LeetCode Hot100 (5-10)

Posted null

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode Hot100 (5-10)相关的知识,希望对你有一定的参考价值。

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

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

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

My Answer:

/**
 * @param {string} s
 * @return {string}
 */
/**
  根据回文对称的特性,从中间向两边进行判断,例如
  aba 是回文,那么在此基础上判断 cabac 时,看最左边和最右边是否相等;
  因此从长度为2到长度为n的字串依次判断(长度为1一定是回文),
  判断过程中使用矩阵 isPalindrome 进行记录
  isPalindrome[i][j]值为1,表示原字符串的第i为到第j为字符串为回文字符串。
 */
var longestPalindrome = function(s) {
    // 字串长度
    let subLength;
    // 处理数组
    let arr=s.split(\'\');
    // 字串最大长度
    let maxLength=1;
    // 返回结果字串
    let resString=arr[0];
    let isPalindrome=Array(arr.length).fill(0).map(x=>Array(arr.length).fill(0));
    
    // 长度为1的字串为回文
    if(arr.length<=1){
        return resString;
    }
    for(let i=0;i<arr.length;i++){
        isPalindrome[i][i]=1;
    }
   
    for(subLength=2;subLength<=arr.length;subLength++){
        for(let i=0;i<=arr.length-subLength;i++){
            let j=i+subLength-1;
            if(subLength===2 && arr[i]===arr[j]){
                isPalindrome[i][j]=1;
                if(arr.slice(i,j+1).length>maxLength){
                    maxLength=arr.slice(i,j+1).length;
                    resString=arr.slice(i,j+1).join(\'\');
                }
            }
            if(arr[i]===arr[j] && isPalindrome[i+1][j-1]){
                isPalindrome[i][j]=1;
                if(arr.slice(i,j+1).length>maxLength){
                    maxLength=arr.slice(i,j+1).length;
                    resString=arr.slice(i,j+1).join(\'\');
                }
            }
        }
    }
    return resString;
};

6. Z 字形变换
将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。

比如输入字符串为 "PAYPALISHIRING" 行数为 3 时,排列如下:
 P   A   H   N
 A P L S I I G
 Y   I   R

之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"PAHNAPLSIIGYIR"。

请你实现这个将字符串进行指定行数变换的函数:

示例 1:
输入:s = "PAYPALISHIRING", numRows = 3
输出:"PAHNAPLSIIGYIR"

提示:
1 <= s.length <= 1000
s 由英文字母(小写和大写)、\',\' 和 \'.\' 组成
1 <= numRows <= 1000

My Answer:

/**
 * @param {string} s
 * @param {number} numRows
 * @return {string}
 */
 /**
   一共有numRows行,每(2*numRows-2)为一组,其中:
   numRows >= 2:
   第一行对应下标 对(2*numRows-2)取余之后为0 的字符;
   第二行对应(2*numRows-2)的倍数 加减 (行数-1) 对应的字符
   ......
   最后一行对应标 对(2*numRows-2)取余之后为(行数-1)的字符;
  */
var convert = function(s, numRows) {
    let resString=\'\';
    // 给定行数为1的情况
    if(s.length<=1||numRows===1){
        return s;
    }
    // 给定行数大于等于2的情况
    for(let row=0;row<numRows;row++){
        let index=row;
        // 第一行和最后一行对应的字符
        if(row===0||row===numRows-1){
            while(index<s.length){
                resString+=s[index];
                index+=2*numRows-2;
            }
        }
        // 其它行对应的字符
        else{
            if(index<s.length){
                resString+=s[index];
            }
            index=2*numRows-2;
            while((index-row)<s.length){ 
                resString+=s[index-row];
                if((index+row)<s.length){
                    resString+=s[index+row];
                }
                index+=2*numRows-2;
            }
        }
    }
    return resString;
};

7. 整数反转
给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。
如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] ,就返回 0。假设环境不允许存储 64 位整数(有符号或无符号)。

示例 1:
输入:x = 123
输出:321

提示:
-231 <= x <= 231 - 1

My Answer:

/**
 * @param {number} x
 * @return {number}
 */
/**
  去0反转判断大小
 */
var reverse = function(x) {
    let i,j;
    let arrX=(\'\'+x).split(\'\');
    let symbolX=1;
    // 正负号处理
    if(arrX[0]===\'-\'){
        arrX.shift();
        symbolX=-1;
    }
    // 去零
    while(arrX[arrX.length-1]===\'0\' && arrX.length>1){
        arrX.pop();
    }
    // 反转
    for(i=0,j=arrX.length-1;i<j;){
        let t=arrX[i];
        arrX[i]=arrX[j];
        arrX[j]=t;
        i++;
        j--;
    }
    // 判断是否超出范围
    if((arrX.join(\'\'))*symbolX>2147483647||(arrX.join(\'\'))*symbolX<-2147483648){
        return 0;
    }
    return (arrX.join(\'\'))*symbolX;
};

8. 字符串转换整数 (atoi)
请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C++ 中的 atoi 函数)。
函数 myAtoi(string s) 的算法如下:

读入字符串并丢弃无用的前导空格
检查下一个字符(假设还未到字符末尾)为正还是负号,读取该字符(如果有)。 确定最终结果是负数还是正数。 如果两者都不存在,则假定结果为正。
读入下一个字符,直到到达下一个非数字字符或到达输入的结尾。字符串的其余部分将被忽略。
将前面步骤读入的这些数字转换为整数(即,"123" -> 123, "0032" -> 32)。如果没有读入数字,则整数为 0 。必要时更改符号(从步骤 2 开始)。
如果整数数超过 32 位有符号整数范围 [−231, 231 − 1] ,需要截断这个整数,使其保持在这个范围内。具体来说,小于 −231 的整数应该被固定为 −231 ,大于 231 − 1 的整数应该被固定为 231 − 1 。
返回整数作为最终结果。
注意:
本题中的空白字符只包括空格字符 \' \' 。
除前导空格或数字后的其余字符串外,请勿忽略 任何其他字符。

示例 1:
输入:s = "42"
输出:42

示例 2:
输入:s = " -42"
输出:-42

示例 3:
输入:s = "4193 with words"
输出:4193

示例 4:
输入:s = "words and 987"
输出:0

示例 5:
输入:s = "-91283472332"
输出:-2147483648

提示:
0 <= s.length <= 200
s 由英文字母(大写和小写)、数字(0-9)、\' \'、\'+\'、\'-\' 和 \'.\' 组成
My Answer:
/**
 * @param {string} s
 * @return {number}
 */
var myAtoi = function(s) {
    // 去除两边空格
    s=s.trim();

    let resS=\'\';
    let symbolS=1;
    let arr=s.split(\'\');

    // 判断正负
    if(arr[0]===\'-\'){
        arr.shift();
        symbolS=-1;
    }
    else if(arr[0]===\'+\'){
        arr.shift();
    }

    // 去除前导0
    while(arr[0]===\'0\' && arr.length>1){
        arr.shift();
    }

    // 读入数字
    for(let i=0;i<arr.length;i++){
        if(arr[i].charCodeAt()>=\'0\'.charCodeAt()&&arr[i].charCodeAt()<=\'9\'.charCodeAt()){
            resS+=arr[i];
            // 溢出处理
            if(resS*symbolS>2147483647){
                return 2147483647;
            }
            if(resS*symbolS<-2147483648){
                return -2147483648;
            }
        }
        else{
            break;
        }
    }

    if(resS)
        return resS*symbolS;
    else
        return 0;
};

9. 回文数
给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。
回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。例如,121 是回文,而 123 不是。

示例 1:
输入:x = 121
输出:true

示例 2:
输入:x = -121
输出:false
解释:从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。
示例 3:

提示:
-231 <= x <= 231 - 1

My Answer:

/**
 * @param {number} x
 * @return {boolean}
 */
var isPalindrome = function(x) {
    let start,end;
    let stringX=\'\'+x;
    let res=true;
    if(stringX.length<=1)
        return true;
    for(start=0,end=stringX.length-1;start<end;){
        if(stringX[start]!==stringX[end]){
            res=false;
            break;
        }
        else{
            start++;
            end--;
        }
    }
    return res;
};

10. 正则表达式匹配
给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 \'.\' 和 \'*\' 的正则表达式匹配。
\'.\' 匹配任意单个字符
\'*\' 匹配零个或多个前面的那一个元素
所谓匹配,是要涵盖 整个字符串 s的,而不是部分字符串。

示例 1:
输入:s = "aa" p = "a"
输出:false
解释:"a" 无法匹配 "aa" 整个字符串。

示例 2:
输入:s = "aa" p = "a*"
输出:true
解释:因为 \'*\' 代表可以匹配零个或多个前面的那一个元素, 在这里前面的元素就是 \'a\'。因此,字符串 "aa" 可被视为 \'a\' 重复了一次。

提示:
0 <= s.length <= 20
0 <= p.length <= 30
s 可能为空,且只包含从 a-z 的小写字母。
p 可能为空,且只包含从 a-z 的小写字母,以及字符 . 和 *。
保证每次出现字符 * 时,前面都匹配到有效的字符

My Answer:

/**
 * @param {string} s
 * @param {string} p
 * @return {boolean}
 */
var isMatch = function(s, p) {
    // 添加开始和结束标志
    let reg=new RegExp(\'^\'+p+\'$\');
    let res=reg.test(s);
    return res;
};

以上是关于LeetCode Hot100 (5-10)的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode 热题 HOT 100 完整题解笔记&知识点分类 C++代码实现

LeetCode 热题 HOT 100

LeetCode Hot 100 --- 括号生成(java图解超级详细)

#yyds干货盘点# LeetCode 热题 HOT 100:子集

LeetCode Hot 100 --- 全排列(java)

leetcode热题Hot100——LRU缓存