写点自己做链表算法题的工具方法

链表对象的定义:

 public static class ListNode {
        int val;
        ListNode next;

        ListNode() {
        }

        ListNode(int val) {
            this.val = val;
        }

        ListNode(int val, ListNode next) {
            this.val = val;
            this.next = next;
        }
    }

快慢指针的妙用:

使用快慢指针找到中点

/*使用快慢指针找到中点
    适用情况:
        1.对于链表个数为奇数个时 返回中点
        2.对于链表个数为偶数个时 返回中点(前一个)

    */
    public static ListNode findMid1(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }

        ListNode slow = head;
        ListNode fast = head;

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

        return slow;
    }
/*使用快慢指针找到中点
    适用情况:
        1.对于链表个数为奇数个时 返回中点
        2.对于链表个数为偶数个时 返回中点(后一个)

    */
    public static ListNode findMid2(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }

        ListNode slow = head;
        ListNode fast = head;

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

        if (fast.next != null) {
            slow = slow.next;
        }

        return slow;
    }

使用快慢指针判断是否有成环问题

/*使用快慢指针判断是否有成环问题*/
    public static boolean isLooped(ListNode head) {
        if (head == null || head.next == null) {
            return false;
        }
        ListNode slow = head;
        ListNode fast = head;

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

            if (slow == fast) {
                return true;
            }
        }

        return false;
    }

使用快慢指针来找到成环的单链表的入环点

/*使用快慢指针来找到成环的单链表的入环点*/
    public static ListNode getLoppNode(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }

        ListNode slow = head;
        ListNode fast = head;

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

            //快慢指针一旦相遇,将快指针指向头节点
            if (slow == fast) {
                fast = head;
                break;
            }
        }

        //为了判断没有环的情况
        if (fast.next == null || fast.next.next == null) {
            return null;
        }

        while (fast != slow) {
            fast = fast.next;
            slow = slow.next;
        }


        return slow;
    }

找到两个不成环的单链表的交点

/*找到两个不成环的单链表的交点*/
    public static ListNode getIntersectionNode1(ListNode head1, ListNode head2) {
        ListNode node1 = head1;
        ListNode node2 = head2;

        while (node1 != node2) {
            node1 = node1 == null ? head2 : node1.next;
            node2 = node2 == null ? head1 : node2.next;
        }

        return node1;
    }

找到两个成环的单链表的交点

/*找到两个成环的单链表的交点
     * 有以下三种情况
     * 1.两个单链表都有环但是不相交
     * 2.相交点(一个)在入环点(一个)前   (和两个不成环的单链表的交点情况一样,只不过终点定为入环点)
     * 3.两个入环点=两个相交点(即中间成环)*/
    public static ListNode getIntersectionNode2(ListNode head1, ListNode head2, ListNode loop1, ListNode loop2) {

        if (loop1 == loop2) {
            //对应第二种情况
            ListNode node1 = head1;
            ListNode node2 = head2;

            while (node1 != node2) {
                node1 = node1 == loop2 ? head2 : node1.next;
                node2 = node2 == loop1 ? head1 : node2.next;
            }

            return node1;
        } else {
            ListNode node1 = loop1.next;
            while (node1 != loop1) {
                if (node1 == loop2) {
                    //说明是第三种情况
                    return loop1;
                }
                node1 = node1.next;
            }
            //说明是第一种情况
            return null;
        }
    }

找交点方法主体

//找交点方法
    public static ListNode getIntersectionNode(ListNode head1, ListNode head2) {
        if (head1 == null || head2 == null) {
            return null;
        }

        ListNode loop1 = getLoppNode(head1);
        ListNode loop2 = getLoppNode(head2);

        if (loop1 == null && loop2 == null) {
            return getIntersectionNode1(head1, head2);
        }

        if (loop1 != null && loop2 != null) {
            return getIntersectionNode2(head1, head2,loop1,loop2);
        }

        return null;
    }

猜你喜欢

转载自blog.csdn.net/Wantbebetter/article/details/121404172