算法题(二)

6. Z 字形变换

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

比如输入字符串为 "PAYPALISHIRING" 行数为 3 时,排列如下:

P   A   H   N
A P L S I I G
Y   I   R
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"PAHNAPLSIIGYIR"。

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

string convert(string s, int numRows);
 

示例 1:

输入:s = "PAYPALISHIRING", numRows = 3
输出:"PAHNAPLSIIGYIR"
示例 2:
输入:s = "PAYPALISHIRING", numRows = 4
输出:"PINALSIGYAHRPI"
解释:
P     I    N
A   L S  I G
Y A   H R
P     I
示例 3:

输入:s = "A", numRows = 1
输出:"A"

解题思路:

r[i] += c: 把每个字符 c 填入对应行si;
j += flag: 更新当前字符 c 对应的行索引;
flag = - flag: 在达到 ZZ 字形转折点时,执行反向。

//java
class Solution {
    public String convert(String s, int numRows) {
        List<StringBuilder> rows=new ArrayList<StringBuilder>();
        int j=0,flag=-1;
        if(s.length()<=0){
            return null;
        }
        if(numRows==1){
            return s;
        }
        for(int i=0;i<numRows;++i) rows.add(new StringBuilder());
        for(char c:s.toCharArray()){
                rows.get(j).append(c);
                if(j==0 || j==numRows-1) flag=-flag;
                j+=flag;
        }
        StringBuilder r=new StringBuilder();
        for(StringBuilder row:rows) r.append(row);
        return r.toString();
    }
}
//java-返回原字符串
class Solution {
    public String convert(String s, int numRows) {
        List<StringBuilder> rows=new ArrayList<StringBuilder>();
        int j=0,flag=-1;
        if(s.length()<=0){
            return null;
        }
        if(numRows==1){
            return s;
        }
        if(numRows<s.length()){
            for(int i=0;i<numRows;++i){
                rows.add(new StringBuilder());
            }
            for(char c:s.toCharArray()){
                rows.get(j).append(c);
                if(j==0 || j==numRows-1){
                    flag=-flag;
                    j+=flag;
                }
            }
        }
        StringBuilder r=new StringBuilder();
        for(StringBuilder row:rows){
            r.append(row);
        }
        return r.toString();
    }
}

7. 整数反转

给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。

如果反转后整数超过 32 位的有符号整数的范围 [−231,  231 − 1] ,就返回 0。

假设环境不允许存储 64 位整数(有符号或无符号)。
 

示例 1:

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

输入:x = -123
输出:-321
示例 3:

输入:x = 120
输出:21
示例 4:

输入:x = 0
输出:0

//java
class Solution {
    public int reverse(int x) {
        int c=0;
        while(x!=0){
            if((c*10)/10!=c){
                c=0;
                break;
            }
            c=c*10+x%10;
            x=x/10;
        }
        return c;
    }
}

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
解释:加粗的字符串为已经读入的字符,插入符号是当前读取的字符。
第 1 步:"42"(当前没有读入字符,因为没有前导空格)
         ^
第 2 步:"42"(当前没有读入字符,因为这里不存在 '-' 或者 '+')
         ^
第 3 步:"42"(读入 "42")
           ^
解析得到整数 42 。
由于 "42" 在范围 [-231, 231 - 1] 内,最终结果为 42 。
示例 2:

输入:s = "   -42"
输出:-42
解释:
第 1 步:"   -42"(读入前导空格,但忽视掉)
            ^
第 2 步:"   -42"(读入 '-' 字符,所以结果应该是负数)
             ^
第 3 步:"   -42"(读入 "42")
               ^
解析得到整数 -42 。
由于 "-42" 在范围 [-231, 231 - 1] 内,最终结果为 -42 。
示例 3:

输入:s = "4193 with words"
输出:4193
解释:
第 1 步:"4193 with words"(当前没有读入字符,因为没有前导空格)
         ^
第 2 步:"4193 with words"(当前没有读入字符,因为这里不存在 '-' 或者 '+')
         ^
第 3 步:"4193 with words"(读入 "4193";由于下一个字符不是一个数字,所以读入停止)
             ^
解析得到整数 4193 。
由于 "4193" 在范围 [-231, 231 - 1] 内,最终结果为 4193 。
示例 4:

输入:s = "words and 987"
输出:0
解释:
第 1 步:"words and 987"(当前没有读入字符,因为没有前导空格)
         ^
第 2 步:"words and 987"(当前没有读入字符,因为这里不存在 '-' 或者 '+')
         ^
第 3 步:"words and 987"(由于当前字符 'w' 不是一个数字,所以读入停止)
         ^
解析得到整数 0 ,因为没有读入任何数字。
由于 0 在范围 [-231, 231 - 1] 内,最终结果为 0 。
示例 5:

输入:s = "-91283472332"
输出:-2147483648
解释:
第 1 步:"-91283472332"(当前没有读入字符,因为没有前导空格)
         ^
第 2 步:"-91283472332"(读入 '-' 字符,所以结果应该是负数)
          ^
第 3 步:"-91283472332"(读入 "91283472332")
                     ^
解析得到整数 -91283472332 。
由于 -91283472332 小于范围 [-231, 231 - 1] 的下界,最终结果被截断为 -231 = -2147483648 。

//java
class Solution {
public int myAtoi(String str) {
    int i=0,t=0,a=1;
    //异常情况:str为空
    if(str.length()<=0 || str==null){
        return 0;
    }
    //去除字符串中空格
    while(i<str.length() && str.charAt(i)==' ') i++;
    //处理特殊字符
    if(i<str.length() && (str.charAt(i)=='+' || str.charAt(i)=='-')){
        a=str.charAt(i)=='+'?1:-1;
        i++;
    }
    //正常计算字符串
   while(i<str.length()){
        int b=str.charAt(i)-'0';
        if(b>9 || b<0) break;
        if((t>(Integer.MAX_VALUE-b)/10)){
            return a>0?Integer.MAX_VALUE:Integer.MIN_VALUE;
        }
        t=t*10+b;
        i++;
    }
    return t*a;
}
}
//java-返回结果第一位进位1
第一种方法:
class Solution {
public int myAtoi(String str) {
    int i=0;
    //异常情况:str为空
    if(str.length()<=0 || str==null){
        return 0;
    }
    //去除字符串中空格
    while(i<str.length() && str.charAt(i)==' '){
        str=str.trim();
        i++;
    }
    //处理特殊字符
    while(i<str.length() && str.charAt(i)=='+' || str.charAt(i)=='-'){
        int a=str.charAt(i)=='+'?1:-1;
        i++;
    }
    return str.charAt(i);
}
}

第二种方法:
class Solution {
public int myAtoi(String str) {
    int i=0,t=1;
    //异常情况:str为空
    if(str.length()<=0 || str==null){
        return 0;
    }
    //去除字符串中空格
    while(i<str.length() && str.charAt(i)==' '){
        str=str.trim();
        i++;
    }
    //处理特殊字符
    while(i<str.length() && str.charAt(i)=='+' || str.charAt(i)=='-'){
        int a=str.charAt(i)=='+'?1:-1;
        i++;
    }
    //正常计算字符串
   while(i<str.length()){
       int b=str.charAt(i);
        if(b>9 || b<0){break;}
        if((t>(Integer.MAX_VALUE-b)/10)){
            return b>0?Integer.MAX_VALUE:Integer.MIN_VALUE;
        }
        t=t*10+b;
        i++;
    }
    return t*str.charAt(i);
}
}
第三种情况,返回结果高位多一位1
class Solution {
public int myAtoi(String str) {
    int i=0,t=1;
    //异常情况:str为空
    if(str.length()<=0 || str==null){
        return 0;
    }
    //去除字符串中空格
    while(i<str.length() && str.charAt(i)==' '){
        str=str.trim();
        i++;
    }
    //处理特殊字符
    while(i<str.length() && str.charAt(i)=='+' || str.charAt(i)=='-'){
        int a=str.charAt(i)=='+'?1:-1;
        i++;
    }
    //正常计算字符串
   while(i<str.length()){
       int b=str.charAt(i)-'0';
        if(b>9 || b<0){break;}
        if((t>(Integer.MAX_VALUE-b)/10)){
            return b>0?Integer.MAX_VALUE:Integer.MIN_VALUE;
        }
        t=t*10+b;
        i++;
    }
    return t;
}
}

9. 回文数

给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。

回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。例如,121 是回文,而 123 不是。

 

示例 1:

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

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

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

输入:x = -101
输出:false

//java
class Solution {
    public boolean isPalindrome(int x) {
        int a=0;
        //负数都不是回文数,正偶数若是0开头,有两种情况:0开头,x不等于0不是回文数
        if(x<0 || (x%10==0 && x!=0)){
            return false;
        }
        if(x==0) return true;
        //中位数不管哪种排序都一样,可忽略
        while(x>a){
            a=a*10+x%10;
            x/=10;
        }
        return x==a || x==a/10;
    }
}

10. 正则表达式匹配

给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.' 和 '*' 的正则表达式匹配。

'.' 匹配任意单个字符
'*' 匹配零个或多个前面的那一个元素
所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。

 
示例 1:

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

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

输入:s = "ab" p = ".*"
输出:true
解释:".*" 表示可匹配零个或多个('*')任意字符('.')。
示例 4:

输入:s = "aab" p = "c*a*b"
输出:true
解释:因为 '*' 表示零个或多个,这里 'c' 为 0 个, 'a' 被重复一次。因此可以匹配字符串 "aab"。
示例 5:

输入:s = "mississippi" p = "mis*is*p*."
输出:false

//java
class Solution {
    public boolean isMatch(String s, String p) {
        int a=s.length();
        int b=p.length();
        boolean[][] t=new boolean[a+1][b+1];
        t[0][0]=true;
        for(int i=0;i<=a;++i){
            for(int j=1;j<=b;++j){
                if(p.charAt(j-1)=='*'){
                    t[i][j]=t[i][j-2];
                    if(matches(s,p,i,j-1)){
                        t[i][j]=t[i][j] || t[i-1][j];
                    }
                }else{
                    if(matches(s,p,i,j)){
                        t[i][j]=t[i-1][j-1];
                    }
                }
            }
        }
        return t[a][b];
    }
    public boolean matches(String s,String p,int i,int j){
        if(i==0)  return false;
        if(p.charAt(j-1)=='.'){
            return true;
        } 
        return s.charAt(i-1)==p.charAt(j-1);
    }
}
//python3
class Solution:
    def isMatch(self, s: str, p: str) -> bool:
        return bool(re.match(p+'$',s))
//java-p为单字符或加上*
class Solution {
    public boolean isMatch(String s, String p) {
        if(s==null &&  p==null) return s.isEmpty();
        if((s.length()==0 || s==null) && (p=="." || p=="*")){
            return s.isEmpty();
        }
        return isMatch(s,p,0,0);
    }
    public boolean isMatch(String s,String p,int i,int j){
        if(j==p.length()) return i==s.length();
        if(j==p.length()-1 || p.charAt(j+1)!='*'){
            return i!=s.length() && (p.charAt(j)=='.' || p.charAt(j)==s.charAt(i))?isMatch(s,p,i+1,j+1):false;
        }else{
            while(i<s.length() && (p.charAt(j)=='.' || p.charAt(j)==s.charAt(i))){
                if(isMatch(s,p,i,j+2)){
                    return false;
                }
                i++;
            }
        return true;
        }
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值