LeetCode 链表:160相交链表 725分隔链表

对于链表还是不甚熟悉啊。。。

160 相交链表

 思路:

这道题自己看其实并没有什么思路。思考的时候主要的难度在于从A和B同时往前走的话,会因为离交点的距离不同“错过”C1这个交点。当然我们可以遍历一遍A链表,把每个元素记下来,再遍历B链表找匹配,这样的空间复杂度为O(n)

好的解法则比较巧妙了(没有套路)

 确实比较巧妙,把握住了L1和L2相等(两个都能找到的起点,和都以交点为终点)的特点,这样两边同时出发,就能以空间复杂度O(1)解决问题。

代码:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        ListNode pA=headA;
        ListNode pB=headB;
        while(pA!=pB)
        {
            if(pA==null)
            {pA=headB;}
            else
            {pA=pA.next;}

            if(pB==null)
            {pB=headA;}
            else
            {pB=pB.next;}
        }
        return pA;

        
    }
}

725分隔链表

 思路:这道题一开始有点点懵,但马上就有了思路,想到了之后还觉得是不是太简单了。但由于对于链表操作层面的不熟,搞了好久都没有把正确的代码写出来(没有理解如何断开链表)

怎么分长度倒是很简单。先遍历求出链表长度len。len/k得到每段平均长度partA,len%k得到前partB段需要在partA上加一

原来的循环想的是分两段循环,先循环partB次,再循环k-partB次。但其实是多此一举,设置一个partB--,再用三元运算符确定+1或+0.

双指针一开始还没想清楚为什么,导致老是搞错。。。其实第一个指针start是用来指下一段开头位置的(用于遍历),end指针则是用于指示start遍历时的上一个位置,最后在完成一段时用于断开前一段的链表!这个断开的操作是关键操作,如果不把上一段的末尾指向null,则会变为[[1,2,3,4],[2,3,4]...]这样。所以,链表的开头取决于这个ListNode=root的root,它的结尾取决于end.next=null的位置在哪。

如何处理null其实也挺巧妙的,因为假如到start已经为null了,那么partA已经变为了0,所以不会出现null.next的报错问题

这张图挺好的,摘录一下:

 代码:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
        public static ListNode[] splitListToParts(ListNode root, int k) {
        int count=0;
        int partA,partB;
        ListNode countroot=root;
        ListNode[] listNodes=new ListNode[k];
        while(countroot!=null)
        {
            count+=1;
            countroot=countroot.next;
        }
        partA=count/k;
        partB=count%k;
        ListNode end=null,start=root;
        for (int i=0;i<k;i++)
        {
            listNodes[i]=start;
            int len=(i<partB)?1:0;
            for (int j=0;j<partA+len;j++)
            {
                end=start;
                start=start.next;
            }
            if (end!=null)
            {end.next=null;}
        }
        return listNodes;

    }
}

两道题需要注意的点:

  • 第一道题的特殊解法
  • 遍历使用的是p=p.next
  • 链表的开头 和结尾分别由什么决定
  • 如何完整遍历链表或求链表长度,判断条件是p!=null
  • 三元运算符的使用
  • 注意出现null.next的常见错误
原文地址:https://www.cnblogs.com/take-it-easy/p/12685436.html