本周专题双指针
先来点java基础知识:Character类的常用方法
方法分类 | 方法描述 |
是否是字母、数字、空白 | isLetterOrDigit( ) isDigit( ) 是否数字 isWhitespace( ) 是否空格 |
大小写判断 | isUpperCase( ) 是否大写字母 isLowerCase( ) 是否小写字母 |
大小写转换 | toUpperCase( ) 转成大写字母 toLowerCase( ) 转成小写字母 |
字符串转换 | toString( ) 转成长度为1的字符串 |
题目:
如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。
字母和数字都属于字母数字字符。
给你一个字符串 s
,如果它是 回文串 ,返回 true
;否则,返回 false
。
示例 1:
输入: s = "A man, a plan, a canal: Panama" 输出:true 解释:"amanaplanacanalpanama" 是回文串。
解题思路:比较简单的双指针题目了,如图所示,从字符串头尾分别定义一个指针,依次遍历,对比是否相等。若有不等的则为false,若全部相同,则返回true。
难点:1、遍历的时候需要跳过非字母或数字的部分,可以用Character.isLetterOrDigit( )
2、对比是否相等时,需要都转成小写字母,可以用Character.toLowerCase( )
class Solution {
public boolean isPalindrome(String s) {
char[] chars = s.toCharArray();
int j = chars.length - 1;
for (int i = 0; i <= j; i++) {
#从头部取非字母或者数字的i
if (Character.isLetterOrDigit(chars[i])) {
#从尾部取非字母或者数字的j
while (!Character.isLetterOrDigit(chars[j])) {
j--;
}
#判断i和j是否相等,不相等则直接返回false,相等j往前移一位,i继续遍历
if (Character.toLowerCase(chars[j]) != Character.toLowerCase(chars[i])) {
return false;
}
j--;
}
}
return true;
}
}
再来一题试
给定一个长度为 n
的整数数组 height
。有 n
条垂线,第 i
条线的两个端点是 (i, 0)
和 (i, height[i])
。
找出其中的两条线,使得它们与 x
轴共同构成的容器可以容纳最多的水。
返回容器可以储存的最大水量。
说明:你不能倾斜容器。
示例 1:
输入:[1,8,6,2,5,4,8,3,7] 输出:49 解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。
思路一:比较暴力,时间复杂度太高了。双重循环,挨个框框遍历一边
class Solution {
public int maxArea(int[] height) {
int re=0;
for(int i=0; i<height.length;i++){
for (int j=i+1;j<height.length;j++){
int x=j-i;
int y=Math.min(height[i],height[j]);
int m=x*y;
if(re < m){
re=m;
}
}
}
return re;
}
}
思路二:容积大小取决于最短边。先从底边最大处开始,每次移动最短边,有可能会比上次的容积大。
class Solution {
public int maxArea(int[] height) {
int i = 0;
int re = 0;
int j = height.length - 1;
while (i < j) {
int s = Math.min(height[i], height[j]) * (j - i);
re = Math.max(re, s);
if (height[i] < height[j]) {
i++;
} else {
j--;
}
}
return re;
}
}