快慢指针 刷题及解答

快慢指针

在初始化设置指向链表头结点时,设置两个指针,快慢指针,前进时快指针fast在前,慢指针slow在后,巧妙解决链表中的一些问题。

判断链表中是否有环

每次快指针多走一步,假设环长为x,当快指针多走x步时会与慢指针相遇

快指针是每次走两步,慢指针每次走一步
而不是快指针一开始指向head的下一个 慢指针指向head 两个一起走

https://leetcode.cn/problems/linked-list-cycle/


public class Solution {
    public boolean hasCycle(ListNode head) {
        ListNode fast = head;
        ListNode slow = head;
        while(fast!=null && fast.next!=null){
            fast = fast.next.next;
            slow = slow.next;
            if(fast==slow) return true;
        }
        return false;
    }
}

https://leetcode.cn/problems/happy-number/

class Solution {
    public int getSum(int n){
        int sum = 0;
        while(n>0){
            sum += (n%10)*(n%10);
            n/=10;
        }
        return sum;
    }
    public boolean isHappy(int n) {
        int fast = getSum(n);
        int slow = n;
        while(fast!=1){
            if(fast==slow) return false;
            fast = getSum(getSum(fast));
            slow = getSum(slow);
        }
        return true;
    }
}

已知链表中含有环,返回这个环的起始位置

https://leetcode.cn/problems/linked-list-cycle-ii/

假设慢指针和快指针相遇,也就是在起始位置,此时slow走了k步,那么快的由于每次走两步,所以一共走了2k步 也就是环的长度是k
相遇点不一定就在环的起始位置(最简单的两个点的就能论证)


public class Solution {
    public ListNode detectCycle(ListNode head) {
        ListNode fast = head;
        ListNode slow = head;
        int k = 0; 
        while(fast!=null && fast.next!=null){
            k++;
            fast = fast.next.next;
            slow = slow.next;
            if(fast==slow){
                fast = head;
                while(fast!=slow){
                    fast = fast.next;
                    slow = slow.next;
                }
                return slow;
            }
        }
        return null;
    }
}

寻找链表的中点

https://leetcode.cn/problems/middle-of-the-linked-list/submissions/

class Solution {
    public ListNode middleNode(ListNode head) {
        ListNode slow = head;
        ListNode fast = head;
        while(fast!=null){
            fast = fast.next;
            if(fast==null) return slow;
            slow = slow.next;
            fast = fast.next;
        }
        return slow;
    }
}

寻找链表的倒数第 k 个元素


class Solution {
    public ListNode getKthFromEnd(ListNode head, int k) {
        ListNode fast = head;
        ListNode slow = head;
        while(k-->0){
            fast = fast.next;
        }
        while(fast!=null){
            fast = fast.next;
            slow = slow.next;
        }
        return slow;
    }
}

剑指 Offer II 026. 重排链表

https://leetcode.cn/problems/LGjMqU/

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public void reorderList(ListNode head) {
        if(head.next==null)
            return ;
        ListNode slow = head;
        ListNode fast = head;

        ListNode tt = slow;
        while(fast!=null && fast.next!=null){
            tt = slow;
            fast = fast.next.next;
            slow = slow.next;
        }
        tt.next = null;

        ListNode pre = slow;
        ListNode prepre = null;
        while(slow!=null){
            pre = slow;
            slow = slow.next;
            pre.next = prepre;
            prepre = pre;
        }
        ListNode head2 = pre;
        //head head2
        while(head!=null){
            ListNode t = head.next;
            head.next = head2;
            head2 = head2.next;
            if(t!=null)
                head.next.next = t;
            head = t;
        }
        
        

    }
}

删除链表的倒数第 N 个结点

https://leetcode.cn/problems/remove-nth-node-from-end-of-list/

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode low = head;
        ListNode fast = head;
        for(int i=0; i<n; i++){
            fast = fast.next;
        }
        if(fast==null){
            head = head.next;
        }
        else{
            while(fast.next!=null){
                fast = fast.next;
                low = low.next;
            }
            low.next = low.next.next;
        }
        return head;
    }
}

234. 回文链表

https://leetcode.cn/problems/palindrome-linked-list/

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public boolean isPalindrome(ListNode head){
        //空或者只有一个:true
        if(head==null || head.next==null)
            return true;
        ListNode fast = head;
        ListNode slow = head;

        ListNode pre = head;
        ListNode prepre = null;
        //边快慢指针边走 边翻转
        while(fast!=null && fast.next!=null){ //走到最后一个的位置前 否则不能next.next
            pre = slow;//注意要pre先走到slow位置 这样slow前移后 之前走过的全改变方向
            fast = fast.next.next;
            slow = slow.next;

            pre.next = prepre;
            prepre = pre;
            // pre = slow;  //放在这里 pre的next是原链表的后半部分 会断开

        }
        //奇数个 否则fast每次都是next next 偶数个最后必为null
        if(fast!=null){
            slow = slow.next;
        }
        while(slow!=null && pre!=null){
            if(slow.val!=pre.val)
                return false;
            slow = slow.next;
            pre = pre.next;
        }
        return true;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值