剑指offer 链表专题 刷题记录(下)

简介: 剑指offer 链表专题 刷题记录(下)

25、复杂链表的复制 (map+分段)


import java.util.HashMap;
public class Solution {
    public RandomListNode Clone(RandomListNode pHead) {
        if(pHead==null){
            return null;
        }
        HashMap<RandomListNode,RandomListNode> map=new HashMap<RandomListNode,RandomListNode>();
        RandomListNode p=pHead;
        //遍历将数据放到map中
        while(p!=null){
            map.put(p,new RandomListNode(p.label));
            p=p.next;
        }
        //复制random和next值
        p=pHead;
        while(p!=null){
           map.get(p).next=map.get(p.next);
           map.get(p).random=map.get(p.random);
           p=p.next;
        }
        return map.get(pHead);
    }
}


/*
public class RandomListNode {
    int label;
    RandomListNode next = null;
    RandomListNode random = null;
    RandomListNode(int label) {
        this.label = label;
    }
}
*/
public class Solution {
    public RandomListNode Clone(RandomListNode pHead) {
        if(pHead==null){
            return null;
        }
        RandomListNode p=pHead;
        ///第一步,首先复制链表和val
        while(p!=null){
            RandomListNode cloneNode=new RandomListNode(p.label);
            RandomListNode nextNode=p.next;
            p.next=cloneNode;
            cloneNode.next=nextNode;
            p=nextNode;
        }
        p=pHead;
        ///第二步,将复制链表中random和next 
        while(p!=null){
            p.next.random=p.random==null?null:p.random.next;
            p=p.next.next;
        }
        ///第三步,拆分链表
        RandomListNode pcloneNode=pHead.next;
        p=pHead;
        while(p!=null){
            RandomListNode cloneNode=p.next;
            p.next=cloneNode.next;
            cloneNode.next=cloneNode.next==null?null:cloneNode.next.next;
            p=p.next;
        }
        return pcloneNode;
    }
}


36、两链表的第一个公共节点


/*
public class ListNode {
    int val;
    ListNode next = null;
    ListNode(int val) {
        this.val = val;
    }
}*/
public class Solution {
    public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
        if(pHead1==null||pHead2==null){
            return null;
        }
        int p1length=0;
        ListNode p1=pHead1;
        while(p1!=null){
            p1length++;
            p1=p1.next;
        }
        int p2length=0;
        ListNode p2=pHead2;
        while(p2!=null){
            p2length++;
            p2=p2.next;
        }
        p1=pHead1;
        p2=pHead2;
        int count=Math.abs(p2length-p1length);
        if(p2length>p1length){
           for(int i=0;i<count;i++){
               p2=p2.next;
           } 
        }else{
            for(int i=0;i<count;i++){
                p1=p1.next;
           }
        }
        while(p1!=null&&p2!=null){
           if(p1==p2){
               return p1;
           }
               p1=p1.next;
               p2=p2.next;
           }
            return null;
    }
}


image.png


两链表的头指针同时出发,当第二次经过第一个公共节点时,会完美相遇


public class Solution {
    public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
        ListNode p1=pHead1;
        ListNode p2=pHead2;
        while(p1!=p2){
            p1=p1!=null?p1.next:pHead2;
            p2=p2!=null?p2.next:pHead1;
        }
        return p1;
    }
}


55、链表中环的入口节点


根据定理,fast,slow指针(快指针走2步,慢指针走1步),如果有环一定会相遇;从相遇点开始 和从 链表的PHead开始走,分别走一步,最终一定会相遇。


/*
 public class ListNode {
    int val;
    ListNode next = null;
    ListNode(int val) {
        this.val = val;
    }
}
*/
public class Solution {
    public ListNode EntryNodeOfLoop(ListNode pHead) {
        ListNode fast=pHead;
        ListNode slow=pHead;
        while(fast!=null&&fast.next!=null){
            fast=fast.next.next;
            slow=slow.next;
            if(fast==slow){
                break;
            }
        }
        if(fast==null||fast.next==null){
            return null;
        }
        fast=pHead;
        while(fast!=slow){
            fast=fast.next;
            slow=slow.next;
        }
        return fast;
    }
}


/*
 public class ListNode {
    int val;
    ListNode next = null;
    ListNode(int val) {
        this.val = val;
    }
}
*/
import java.util.HashSet;
public class Solution {
    public ListNode EntryNodeOfLoop(ListNode pHead) {
        HashSet<ListNode> set=new HashSet<ListNode>();
        while(pHead!=null){
            if(set.contains(pHead)){
                return pHead;
            }else{
                set.add(pHead);
            }
            pHead=pHead.next;
        }
        return null;
    }
}


56、删除链表中重复节点


/*
 public class ListNode {
    int val;
    ListNode next = null;
    ListNode(int val) {
        this.val = val;
    }
}
*/
public class Solution {
    public ListNode deleteDuplication(ListNode pHead) {
        if(pHead==null||pHead.next==null)
            return pHead;
        ListNode Head=new ListNode(-1);
        Head.next=pHead;
        ListNode pre=Head;
        ListNode last=Head.next;
        while(last!=null){
            //判读是否和下一位相等
            if(last.next!=null&&last.val==last.next.val){
                while(last.next!=null&&last.val==last.next.val){
                    last=last.next;
                }
                pre.next=last.next;
                last=last.next;
            }else{
                pre=pre.next;
                last=last.next;
            }
        }
        return Head.next;
    }
}
目录
相关文章
|
4月前
|
Python
【Leetcode刷题Python】21. 合并两个有序链表
介绍了几种不同的方法来合并多个已排序的链表,包括暴力求解、使用小顶堆以及分而治之策略。
46 2
|
4月前
|
程序员
【刷题记录】移除链表元素
【刷题记录】移除链表元素
|
4月前
|
索引 Python
【Leetcode刷题Python】328. 奇偶链表
在不使用额外空间的情况下,将链表中的奇数和偶数索引节点重新排序的方法,并提供了相应的Python实现代码。
43 0
|
4月前
|
Python
【Leetcode刷题Python】25.K 个一组翻转链表
解决LeetCode "K 个一组翻转链表" 问题的三种方法:使用栈、尾插法和虚拟节点顺序法,并提供了每种方法的Python实现代码。
38 0
|
2月前
(剑指offer)18、删除链表的节点—22、链表中倒数第K个节点—25、合并两个排序的链表—52、两个链表的第一个公共节点(2021.12.07)
(剑指offer)18、删除链表的节点—22、链表中倒数第K个节点—25、合并两个排序的链表—52、两个链表的第一个公共节点(2021.12.07)
56 0
|
4月前
|
Python
【Leetcode刷题Python】114. 二叉树展开为链表
LeetCode上114号问题"二叉树展开为链表"的Python实现,通过先序遍历二叉树并调整节点的左右指针,将二叉树转换为先序遍历顺序的单链表。
30 3
【Leetcode刷题Python】114. 二叉树展开为链表
|
4月前
【刷题记录】链表的回文结构
【刷题记录】链表的回文结构
|
4月前
|
Python
【Leetcode刷题Python】剑指 Offer 22. 链表中倒数第k个节点
Leetcode题目"剑指 Offer 22. 链表中倒数第k个节点"的Python解决方案,使用双指针法找到并返回链表中倒数第k个节点。
58 5
|
4月前
|
Python
【Leetcode刷题Python】剑指 Offer 18. 删除链表的节点
Leetcode题目"剑指 Offer 18. 删除链表的节点"的Python解决方案,通过使用双指针法找到并删除链表中值为特定数值的节点,然后返回更新后的链表头节点。
46 4
|
4月前
|
存储 Python
【Leetcode刷题Python】23. 合并K个升序链表
合并K个升序链表的方法:使用数组排序的暴力求解法、使用小顶堆的高效方法,以及分而治之的策略,并提供了相应的Python实现代码。
26 1

热门文章

最新文章