125. 验证回文串
class Solution {
public boolean isPalindrome(String s) {
StringBuffer sgood = new StringBuffer();
int n=s.length();
for(int i=0;i<n;i++){ //遍历每一个字符串,若是字母或数字,就将该字母转化为小写,添加到Sgood字符串容器内
char ch=s.charAt(i);
if(Character.isLetterOrDigit(ch)){
sgood.append(Character.toLowerCase(ch));
}
}
int length=sgood.length();//不用反转字符串验证的话,可以试左右指针内移验证是否相等
int l=0;int r=length-1;
while(l<r){
if(sgood.charAt(l)!=sgood.charAt(r)){
return false;
}
l++;
r--;
}
return true;
}
}
392.判断子序列
class Solution {
public boolean isSubsequence(String s, String t) {
//两个字符串都只由小写字符组成
int m=s.length();int i=0;
int n=t.length();int j=0;
while(i<m&&j<n){
if(s.charAt(i)==t.charAt(j)){//子字符串判断是否有与木字符串一致的字符
i++;
}
j++;//母字符串一次遍历
}
return i==m;//子字符串遍历完,说明t包含s
}
}
167. 两数之和 II - 输入有序数组
class Solution {
public int[] twoSum(int[] numbers, int target) {
int l=0; int r=numbers.length-1;
int num[]=new int [2];//用来存放最后的两个索引
while(l<r){//每个输入只对应唯一的答案 ,而且不可以重复使用相同的元素。即l和r不可能相等
if(numbers[l]+numbers[r]<target){//最小的+最大的<目标 ,则最小的需要变大,即l++(数组已按非递减顺序排列)
l++;
}else if(numbers[l]+numbers[r]>target){
r--;
}//最小的+最大的>目标 ,则最大的需要变小,即r--(数组已按非递减顺序排列)
else{//最小的+最大的=目标
num[0]=l+1;num[1]=r+1;//下标从 1 开始的整数数组 numbers
break;
}
}
return num;
}
}
11. 盛最多水的容器
class Solution {
public int maxArea(int[] height) {
/*若向内 移动短板 ,水槽的短板 min(h[i],h[j])min(h[i], h[j])min(h[i],h[j]) 可能变大,因此下个水槽的面积 可能增大 。
若向内 移动长板 ,水槽的短板 min(h[i],h[j])min(h[i], h[j])min(h[i],h[j]) 不变或变小,因此下个水槽的面积 一定变小 。*/
int maxArea=0 ;
int l=0; int r=height.length-1;
while(l<r){
//围成面积为height[l],height[r]两者中的较短边和坐标之差
maxArea=Math.max(maxArea,(r-l)*Math.min(height[l],height[r]));
if(height[r]>=height[l]){
//右边较高,所以往后推进的时候面积变化取决于左边的高,移动左边向右
l++;
}
else{//反之,移动右边向左
r--;
}
}
return maxArea;
}
}
15. 三数之和
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
Arrays.sort(nums);//暴力三重循环会有重复解,为避免重复解,先排个序
int n=nums.length;
List<List<Integer>> res=new ArrayList<List<Integer>>();
for (int i=0;i<n-1;i++){
int l=i+1;int r=n-1;
//套用两束之和模板,三数之和(0)——>两数之和?=第三个数的相反数
int target=-nums[i];
if(i>0&&nums[i]==nums[i-1]){//当i>0&&nums[i]==nums[i-1]时,i-1指向的所有组合已加入到结果中,本次双指针搜索只会得到重复组合。
/*ps:为啥要i>0;因为有[0,0,0]这种恶心示例 */
continue;//排序后相邻元素相等时,使用双指针仍然可能有重复解。[1,2,2,-3,4]
}
else{
//排除特殊重复解后,即可套两数之和模板
while(l<r){
if(nums[l]+nums[r]==target){
List<Integer> list=new ArrayList<Integer>();
list.add(nums[i]);
list.add(nums[r]);
list.add(nums[l]);
res.add(list);
//找到后需要继续往下找,左右指针内移
l++;r--;
/* [-2,0,0,2,2]:在指定某一元素(-2),一次双指针内部找到后三元组(l=1,r=4:[-2,0,2])后,需要继续往下找,左右指针内移时仍要避免重复解(l=2,r=3仍是重复解[-2,0,2])*/
while(l<r && nums[l]==nums[l-1]){l++;}//注意:不添加l<r的限制,可能会[4,1,1,1,-3,-5,4]这种左右指针越界
while(l<r && nums[r]==nums[r+1]){r--;}//跳过所有重复的nums[l]和nums[r],防止记录到重复组合。
}
else if(nums[l]+nums[r]<target){//两数之和小于目标值,左指针右移
l++;
}
else if(nums[l]+nums[r]>target){
r--;//两数之和大于目标值,右指针左移
}
}
}
}
return res;
}
}
测试样例好过,提交之后一堆情况……