leetcode刷题--双指针

本文通过多个编程问题的解决方案,展示了双指针在算法中的应用,包括有序数组求和、平方数之和、反转字符串元音、验证回文字符串、合并有序数组和环形链表检测。这些例子详细解释了如何利用双指针有效地解决不同类型的计算机科学问题。
摘要由CSDN通过智能技术生成

167.有序数组Two Sum

使用双指针,一个指向最左边,一个指向最右边,判断与目标target的大小关系

  • 如果l+r>target,右边的r向左移
  • 如果l+r<target,左边的l向右移
 public int[] twoSum(int[] numbers, int target) {
        int []res=new int[2];
        int l=0,r=numbers.length-1;
        while(l<r){
            if(numbers[l]+numbers[r]>target){
                r--;
            }else if(numbers[l]+numbers[r]<target){
                l++;
            }else{
                res[0]=l+1;
                res[1]=r+1;
                return res;
            }
        }
        return new int[0];
    }

633. 平方数之和

题目:给定一个非负整数 c ,你要判断是否存在两个整数 a 和 b,使得 a2 + b2 = c 。
思路:双指针,左边从0开始,右边取c的开平方,

  • 如果ll+rr>target,r向左移
  • 如果ll+rr<target,l向右移
 public boolean judgeSquareSum(int c) {
        int r=(int)Math.sqrt(c),l=0;
        while(l<=r){
            if(r*r+l*l<c){
                l++;
            }else if(r*r+l*l>c){
                r--;
            }else {
                return true;
            }
        }
        return false;
    }

345. 反转字符串中的元音字母

题目:编写一个函数,以字符串作为输入,反转该字符串中的元音字母。
思路:双指针,从两边开始

  • 遇到两边都是元音字母就交换,然后移动
  • 一边是一边不是,不是的那边移动
  • 都不是,都移动
 public String reverseVowels(String s) {
        char[]ch=s.toCharArray();
        int l=0,r=s.length()-1;
        while(l<r){
            if(isyuan(ch[l])&&isyuan(ch[r])){
                char temp=ch[l];
                ch[l]=ch[r];
                ch[r]=temp;
                r--;
                l++;
            }else if(isyuan(ch[l])){
                r--;
            }else if(isyuan(ch[r])){
                l++;
            }else{
                r--;
                l++;
            }
        }
        return String.valueOf(ch);
    }
    public boolean isyuan(char c){
        if(c=='a'||c=='e'||c=='i'||c=='o'||c=='u'||c=='A'||c=='E'||c=='I'||c=='O'||c=='U'){
            return true;
        }
        return false;
    }

680. 验证回文字符串 Ⅱ

题目:给定一个非空字符串 s,最多删除一个字符。判断是否能成为回文字符串。
思路:从两边遍历,如果相等就向中间移动,如果不相等,就判断去掉一个字符后能否相等(只要有一边能相等即可)z

public boolean validPalindrome(String s) {
        int l=0,r=s.length()-1;
        while(l<r){
            if(s.charAt(l)==s.charAt(r)){
                l++;
                r--;
            }else{
                return isPalindrome(s,l,r-1)||isPalindrome(s,l+1,r);
            }
        }
        return true;
    }
    public boolean isPalindrome(String s,int l,int r) {
        while(l<r){
            if(s.charAt(l)==s.charAt(r)){
                l++;
                r--;
            }else{
                return false;
            }
        }
        return true;
    }


88. 合并两个有序数组

题目:给你两个有序整数数组 nums1 和 nums2,请你将 nums2 合并到 nums1 中,使 nums1 成为一个有序数组。
思路:关键是先将较大的数填到nums1末尾

 public void merge(int[] nums1, int m, int[] nums2, int n) {
        int l=0,r=m+n-1;
        while(m>0&&n>0) {
            if(nums1[m-1]>=nums2[n-1]){
                nums1[r]=nums1[m-1];
                m--;
            }else {
                nums1[r]=nums2[n-1];
                n--;
            }
            r--;
        }
        if(n>0){
            for (int i = 0; i <n; i++) {
                nums1[i]=nums2[i];
            }
        }
    }

141. 环形链表

题目:给定一个链表,判断链表中是否有环。
思路:快慢指针,如果两个指针最终相遇,则表明有环。

 public boolean hasCycle(ListNode head) {
        if(head==null)return false;
        ListNode p=head,q=head.next;
        while(p!=null&&q!=null&&q.next!=null){
            if(p==q)return true;
            p=p.next;
            q=q.next.next;
        }
        return false;
    }

524. 通过删除字母匹配到字典里最长单词

题目:给定一个字符串和一个字符串字典,找到字典里面最长的字符串,该字符串可以通过删除给定字符串的某些字符来得到。如果答案不止一个,返回长度最长且字典顺序最小的字符串。如果答案不存在,则返回空字符串。
思路:先写个函数判断s1是不是s的子串,如果是的话就加入hashmap中,map的键是s1的长度,值是s1,如果字典中1.没有那个键2.有键但是值的字典顺序大于s1,就将s1加入字典
坑:字典顺序不是指在链表里的顺序,是它本身的顺序 ab<ba 用s1.compareTo(s2)判断,s1比s2靠前,则返回一个负值

 public static String findLongestWord(String s, List<String> d) {
        int max=0;
        Map<Integer,String>map=new HashMap<>();
        for (String s1 : d) {
            if(isSubString(s,s1)){
                int key=s1.length();
                if((map.get(key)==null)||(map.get(key)!=null&&s1.compareTo(map.get(key))<0)){
                    map.put(key,s1);
                }
                if(max<key)max=key;
            }
        }
        return map.get(max)==null?"":map.get(max);
    }
    public static boolean isSubString(String s1,String s2){
        int i=0,j=0;
        while(j<s2.length()&&i<s1.length()){
            if(s1.charAt(i)==s2.charAt(j)){
                i++;
                j++;
            }else{
                i++;
            }
        }
        return j == s2.length();
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值