leetcode 7
整数反转
这道题对于溢出处理和数据格式有考察,
关于回文可以使用栈FILO
code:
class Solution {
public int reverse(int x) {
int stack=0;
while(x!=0)
{
if((long)stack*10>2147483647||(long)stack*10<-2147483648) return 0;
stack=stack*10+x%10;
x=x/10;
}
return stack;
}
}
leetcode 8
字符串转换整数 (atoi)
此题和上一题一样可以使用栈解决问题,注意解决符号和溢出
code:
class Solution {
public int myAtoi(String str) {
long stack=0;
boolean flag=false;
boolean sign=true;
for(int i=0;i<str.length();i++)
{
if(flag==true&&(str.charAt(i)>'9'||str.charAt(i)<'0')) break;
if(str.charAt(i)=='-') {sign=false; flag=true;}
if(str.charAt(i)=='+') {sign=true;flag=true;}
if(str.charAt(i)<='9'&&str.charAt(i)>='0')
{
int s=(sign==true)?1:-1;
stack=stack*10;
stack+=(int)str.charAt(i)-48;
if((long)stack*s>2147483647) return 2147483647;
if((long)stack*s<-2147483648)return -2147483648;
flag=true;
}
if(flag==false&&str.charAt(i)!=' ') return 0;
}
return sign==true?(int)stack:(int)stack*-1;
}
}
leetcode 9
回文数
此题思路和leetcode 7一样
code:
class Solution {
public boolean isPalindrome(int x) {
if(x<0) return false;
int stack=0;
int x1=x;
while(x!=0)
{
stack=stack*10+x%10;
x=x/10;
}
return (stack==x1)?true:false;
}
}
稍微改进一下,由于整数不以0开头,所以以0结尾的不是回文数
code:
class Solution {
public boolean isPalindrome(int x) {
if(x<0|| (x % 10 == 0 && x != 0)) return false;
int stack=0;
int x1=x;
while(x!=0)
{
stack=stack*10+x%10;
x=x/10;
}
return (stack==x1)?true:false;
}
}
leetcode10
正则表达式匹配 此题涉及回溯和动态规划,对初学者很有意义
对于子问题的解包含子问题的子问题,需考虑回溯和动态规划
可用递归实现
code:
leetcode 11
盛最多水的容器
最简单暴力求解,算出任意两个壁的容量,取最大。
class Solution {
public int maxArea(int[] height) {
int max=0;
for(int i=0;i<height.length;i++)
{
for(int j=0;j<height.length;j++)
{
int p=((j+1)-(i+1))*Math.min(height[i],height[j]);
max=p>max?p:max;
}
}
return max;
}
}
当然非常的慢
可以稍微优化一下,剪枝,每一次判断max都是用之前区间的max和增加一个新壁与之前集合的容量max比较
code:
class Solution {
public int maxArea(int[] height) {
int max=0;
for(int i=1;i<height.length;i++)
{
for(int j=0;j<i;j++)
{
int p=((i+1)-(j+1))*Math.min(height[i],height[j]);
max=p>max?p:max;
}
}
return max;
}
}
也不是很快,可以考虑另一种方法
由于问题中,壁高时,x大一定大于壁低时 x小
所以我们将指针l,r定在两端,只移动短的一端
因为:v=(r-l)*min(hr,hl) 如果hr>hl
移动短边 :v=(r-l-1)*min(hr,hl+z) z为整数
移动场边:v=(r-l-1)*min(hr+z,hl)z为整数
对于短边而言,如果z为正数则 v可能增加
低于长边 移动后的v一定小于移动前。
所以只需要移动短边,遍历取最大即可。
code:
class Solution {
int max=0;
public int maxArea(int[] height) {
int l=0;
int r=height.length-1;
while(true)
{
if(l==r) break;
int p=((r+1)-(l+1))*Math.min(height[l],height[r]);
max=p>max?p:max;
if(height[r]>height[l]) l++;
else r--;
}
return max;
}
}