直通BAT算法面试——链表

题一:链表分化

/** * 题干: * 对于一个链表,我们需要用一个特定阈值完成对它的分化,使得小于等于这个值的结点移到前面,大于该值的结点在后面,同时保证两类结点内部的位置关系不变。 * 给定一个链表的头结点head,同时给定阈值val,请返回一个链表,使小于等于它的结点在前,大于等于它的在后,保证结点值不重复。 * 测试样例: * {1,4,2,5},3 * {1,2,4,5} * * 解析:这是一个经典的荷兰过期问题,只是在这里要求在链表中完成;通过维护三个链表来完成,具体如下 * 小于链表、等于链表、大于链表 * 在维护的时候需要通过指针记录小于链表的尾部,需要通过指针记录等于链表的头部和尾部,需要通过指针记录大于链表的头部。 * 最后就可以通过以上的四个指针将三个链表连在一起。 * * */

    class Solution{
        public  void solve(){
// 代码略
        }


    }

题二:打印两个升序链表的公共值

/** * 题干: * 现有两个升序链表,且链表中均无重复元素。请设计一个高效的算法,打印两个链表的公共值部分。 * 给定两个链表的头指针headA和headB,请返回一个vector,元素为两个链表的公共部分。请保证返回数组的升序。两个链表的元素个数均小于等于500。保证一定有公共值 * 测试样例: * {1,2,3,4,5,6,7},{2,4,6,8,10} * 返回:[2.4.6] * * 解析:因为链表是有序的所以很简单,假设链表A,B。 * 首先从链头开始比较两个链表,如果A 的当前元素等于B的当前元素,那就打印他们的当前元素,并且A、B同时指向他们的下一个元素, * 如果A、B的当前元素关系不是等于,那么就将较小的一方指针向前指一位,一直到找到相等的或者他们的大小关系反过来,循环此操作直到其中一个链表走完 * * * */
class Solution{
        public  int[] solve(ListNode headA, ListNode headB) {
             // write code here
            if (headA == null || headB == null) {
                return null;
            }
            List<Integer> list = new ArrayList<>();
            while (headA != null && headB != null) {
                if (headA.val > headB.val) {
                    headB = headB.next;
                } else if (headA.val < headB.val) {
                    headA = headA.next;
                } else {
                    list.add(headA.val);
                    headA = headA.next;
                    headB = headB.next;
                }
            }
            int[] result = new int[list.size()];
            int i = 0;
            for (int j = 0; j < list.size(); j++) {
                result[j] = list.get(j);
            }
            return result;
        }


    }

    public class ListNode {
        int val;
        ListNode next = null;

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

题四:
如何证明一个链表里面有环,并且返回第一个入环的节点。可以利用快慢指针来解决。
用一个快慢指针,快指针每次走两个节点,慢指针每次走一个节点,如果快慢指针能够相遇那么就代表存在环,接下来将慢指针指向头结点。重新开始往前走还是每次走一步,快指针也是同时开始往前走,但是这次一次走一个节点,他们下一次相遇的地方就是入环的第一个节点。

如果不存在环,那么在第一次快慢指针走的时候肯定是快指针走到null值他们也没有相遇。

具体证明如下:《直通BAT算法面试——链表》

题五:
证明两个单链表是否相交,如果相交请返回他们相交的第一个节点。

分析对于单链表如果他们相交那么相交节点以后的节点肯定 都是两个链表的共同节点。而且对于有环节点和无环节点还需分不同情况讨论。
即:1.2.3三种状况
《直通BAT算法面试——链表》

对于途中1.2他们都是属于一种情况就是在入环节点以前就相交。

所以这道题的关键就在于讨论是否存在环;
(1)如果不存在环,直接先遍历一遍两个节点,得出两个节点长度的差值,然后较长的节点再从头结点开始遍历差值个节点(剩下未遍历部分的节点数一样),然后两个链表同时向下遍历,如果在尾节点之前他们存在相等的节点那么存在相交。反之。
(2)如果不存在环,先分别找出入环节点(如果入环节点一样那么一定是情况1)然后再分别遍历两节点,一直遍历到两节点的入环节点统计出这段的长度。然后再去执行(1)找出在他们入环之前的相交节点。

如果存在环而且经过(2)以后仍然没有搜索到相交的节点那么只有情况3能满足了,要满足情况三,就选取其中一个入环节点向下遍历,而且一定能够遍历到另一个入环节点。如果能则他们两个入环节点中的任意一个都是他们的首次相交节点。

    原文作者:yinbingqiu
    原文地址: https://blog.csdn.net/yinbingqiu/article/details/68065984
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞