leetcode面试150题双指针

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;
    }
}

提交记录
测试样例好过,提交之后一堆情况……

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值