将一个给定字符串 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();
}
}
给你一个 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;
}
}
请你来实现一个 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;
}
}
给你一个整数 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;
}
}
给你一个字符串 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;
}
}
}