leetcode list链表练习题(二)

leetcode 61.旋转链表
给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数。
示例 1:
输入: 1->2->3->4->5->NULL, k = 2
输出: 4->5->1->2->3->NULL
解释:
向右旋转 1 步: 5->1->2->3->4->NULL
向右旋转 2 步: 4->5->1->2->3->NULL

解题:找到关键节点的位置,从中间断链连接
public ListNode rotateRight(ListNode head, int k) {

    if(head == null || head.next == null)
        return head;
    ListNode end = head;
    int len = 0;
    while ( end.next != null ){
        end = end.next;
        len++;
    }
    len++;

    k = k % len;
    if(k == 0 )
        return head;

    ListNode temp = head;
    for(int i = len;i > k + 1;i--){
        temp = temp.next;
    }
    end.next = head;
    head = temp.next;
    temp.next = null;
 
    return head;
}

leetcode 141.环形链表
给定一个链表,判断链表中是否有环。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
示例:
输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。
在这里插入图片描述
解题:设定一个快指针和慢指针,假如链表有环,快指针将追上慢指针
public boolean hasCycle(ListNode head) {

    if(head == null || head.next == null)
        return false;
    ListNode fast = head.next;
    ListNode slow = head;
    while(fast != null){
        if(fast == slow){
            return true;
        } else {
            fast = fast.next;
            if(fast == null)
                return false;
            else {
                fast = fast.next;
                slow = slow.next;
            }
        }      
    }
    return false;
}

leetcode 142.环形链表II
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
说明:不允许修改给定的链表。

解题:起始位置到入环节点的距离等于相遇节点到入环节点的距离,因此接上题,使用快慢指针找到两指针相遇点,求指针从开始节点出发和从相遇位置出发的相遇节点
public ListNode detectCycle(ListNode head) {

    if(head == null || head.next == null)
        return null;
    ListNode fast = head;
    ListNode slow = head;
    ListNode meet = null;
    while(fast.next != null && fast.next.next != null) {
        fast = fast.next.next;
        slow = slow.next; 
        if(fast == slow){
            meet = fast;
            fast = head;
            break;
        }
    }
    while(meet != null ) {
        if(meet == fast)
            break;
        fast = fast.next;
        meet = meet.next;
    }  
    return meet;
}

leetcode 160相交链表
编写一个程序,找到两个单链表相交的起始节点。
如下面的两个链表:
在这里插入图片描述
在节点 c1 开始相交。
注意:
如果两个链表没有交点,返回 null.
在返回结果后,两个链表仍须保持原有的结构。
可假定整个链表结构中没有循环。
程序尽量满足 O(n) 时间复杂度,且仅用 O(1) 内存。
解题:双指针法,假设两个链表相交,设A的长度为a+c,B的长度为b+c(a,b分别为不相交链表长度,c为公共个链表长度),那么将链表A延长b+c,链表B延长a+c,两指针同时向后移动,必定在相交节点相遇,否则为null
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {

    ListNode cursorA = headA;        
    ListNode cursorB = headB;        
    if (cursorA == null || cursorB == null)            
        return null;        
    while (cursorA != cursorB){ 
        if (cursorA == null)
            cursorA = headB; 
        else     
            cursorA = cursorA.next;
            
        if (cursorB == null)
            cursorB = headA;
        else
            cursorB = cursorB.next;
    }        
    return cursorA;
}

leetcode 23.合并k个排序链表
合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。
示例:
输入:
[
1->4->5,
1->3->4,
2->6
]
输出: 1->1->2->3->4->4->5->6

解题:采用优先级队列,将所有链表的队首入列,每次取出当前最小队首元素,直到所有链表为空
public ListNode mergeKLists(ListNode[] lists) {

    ListNode head = null,end = null,temp = null;
    Queue<ListNode> p = new PriorityQueue<>((a,b)->a.val-b.val);
    for(int i = 0;i < lists.length;i++){
        if(lists[i] != null)
            p.add(lists[i]);
    }
    while (!p.isEmpty()){
        temp = p.poll();
        if(head == null){
            head = temp;
        } else {
            end.next = temp;
        }
        end = temp;
        if(temp.next != null){
            p.add(temp.next);
        }
        end.next = null;
    }
    return head;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值