链表相关操作

102 阅读1分钟

1. 删除排序链表的重复元素, 使得每个元素只出现一次

// leetcode 83class Solution {    public ListNode deleteDuplicates(ListNode head) {        if(head == null){            return null;        }        ListNode cur = head;        while(cur!=null && cur.next!=null){            if(cur.val == cur.next.val){                cur.next = cur.next.next;            }else{                cur = cur.next;            }        }        return head;    }}

2.  删除排序链表所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字

//leetcode 82
class Solution {    public ListNode deleteDuplicates(ListNode head) {        if(head == null){            return  head;        }        ListNode dummyNode = new ListNode(0, head);        ListNode pre = dummyNode;        ListNode cur = head;        while(cur!=null){            ListNode diff = cur;            int sameNum = 0;            //从当前节点开始,遍历和当前节点相同的节点个数            while(diff!=null && diff.val == cur.val){                sameNum++;                diff = diff.next;            }             if(sameNum>1){                pre.next = diff;            }else{                pre = cur;            }            cur = diff;        }        return dummyNode.next;    }}

3. 反转一个单链表

// leetcode 206

//方法一:迭代
class Solution {    public ListNode reverseList(ListNode head) {        if(head==null){            return head;        }        ListNode pre = null;        ListNode cur = head;        while(cur!=null){            ListNode temp = cur.next;            cur.next = pre;            pre = cur;            cur = temp;        }        return pre;    }}
//方法二:递归
class Solution {    public ListNode reverseList(ListNode head) {        if(head==null || head.next == null){            return head;        }        ListNode new_head = reverseList(head.next);        head.next.next = head;        head.next = null;        return new_head;    }}

4.  反转从位置m到n的链表

// leetcode 90 
// pre 一直指向需要left的前一个节点,cur一直指向left的那个节点,一直将cur后面的节点插入到pre的后面
class Solution {    public ListNode reverseBetween(ListNode head, int left, int right) {        ListNode dummy_node = new ListNode(-1,head);        ListNode cur =  head;        ListNode pre = dummy_node;        int index = 1;        while(index < left){            index ++;            pre = cur;            cur = cur.next;        }        while(index<right){            ListNode temp = cur.next;            cur.next = temp.next;            temp.next = pre.next;            pre.next = temp;            index ++;        }        return dummy_node.next;    }}

5. 合并两个有序链表

// leetcode 21
// 方法一:递归
class Solution {    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {       if(l1==null){           return l2;       }       if(l2 == null){           return l1;       }       if(l1.val<l2.val){           l1.next = mergeTwoLists(l1.next, l2);           return l1;       }else{           l2.next = mergeTwoLists(l1, l2.next);           return l2;       }    }}
//方法二:迭代
class Solution {    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {       ListNode pre_none  = new ListNode();       ListNode pre = pre_none;       while(l1!=null && l2!=null){           if(l1.val<l2.val){               pre.next = l1;               l1 = l1.next;           }else{                pre.next = l2;               l2 = l2.next;           }           pre = pre.next;       }       // 最后肯定有一个为空,另一个不为空       if(l1 == null){           pre.next = l2;       }else{           pre.next = l1;       }       return pre_none.next;    }}

6.  分隔链表

// leetcode 86class Solution {    public ListNode partition(ListNode head, int x) {        ListNode small_node = new ListNode(-1,head);        ListNode large_node = new ListNode(-1,head);        ListNode small_head = small_node;        ListNode large_head = large_node;        ListNode cur = head;        while(cur!=null){            if(cur.val<x){               small_head.next = cur;               small_head = small_head.next;            }else{                large_head.next = cur;                large_head = large_head.next;            }            cur = cur.next;        }        large_head.next = null;        small_head.next = large_node.next;        return small_node.next;    }}

7. 排序列表

// leetcode 148
//方法一: 递归-自顶向下归并排序
class Solution {    public ListNode sortList(ListNode head) {        return sortList(head,null);    }    public ListNode sortList(ListNode head,ListNode tail){        if(head == null){            return null;        }        if(head.next == tail){            head.next = null;            return head;        }        ListNode slow = head;        ListNode fast = head;        while(fast != tail){            slow = slow.next;            fast = fast.next;            if(fast != tail){                fast = fast.next;            }        }        ListNode mid = slow;        ListNode list1 = sortList(head,mid);        ListNode list2 = sortList(mid,tail);        ListNode sorted = merge(list1, list2);        return sorted;    }    public ListNode merge(ListNode l1, ListNode l2){        ListNode dummy_node = new ListNode(-1);        ListNode pre = dummy_node;        while(l1!=null && l2!=null){            if(l1.val < l2.val){                pre.next = l1;                l1 = l1.next;            }else{                pre.next = l2;                l2 = l2.next;            }            pre = pre.next;        }        if(l1==null){            pre.next = l2;        }else{            pre.next = l1;        }        return dummy_node.next;    }}
//方法二-自底向上归并迭代

8. 重排链表

// leetcode 143
//方法一:线性表class Solution {    public void reorderList(ListNode head) {        List<ListNode> list = new ArrayList<>();        ListNode node = head;        while(node!=null){            list.add(node);            node = node.next;        }           int size = list.size();        int i = 0;        int j = size-1;        while(i<j){            list.get(i).next = list.get(j);            i++;            list.get(j).next = list.get(i);            j--;        }        list.get(i).next = null;    }}
//方法二:
class Solution {    public void reorderList(ListNode head) {        if(head == null){            return;        }
       // 选择中间节点,把list截成两段,翻转后面的那一段,然后再合并       ListNode mid = midNode(head);       ListNode l1 = head;       ListNode l2 = mid.next;       mid.next = null;           l2 = reverse(l2);       merge(l1,l2);    }    public ListNode midNode(ListNode head){        ListNode slow = head;        ListNode fast = head;        while(fast!=null && fast.next!=null && fast.next.next!=null){            slow = slow.next;            fast = fast.next.next;        }        return slow;    }    public ListNode reverse(ListNode head){        ListNode pre = null;        ListNode cur = head;        while(cur!=null){            ListNode temp = cur.next;            cur.next = pre;            pre = cur;            cur = temp;        }        return pre;    }    public void merge(ListNode l1, ListNode l2){         ListNode l1_tmp ;         ListNode l2_tmp ;        while(l1!=null && l2!=null){            l1_tmp = l1.next;            l2_tmp = l2.next;            l1.next = l2;            l1 = l1_tmp;            l2.next = l1;            l2 = l2_tmp;        }    }    }

9. 环形链表

// leetcode 142
// 方法一:用一个set
public class Solution {    public ListNode detectCycle(ListNode head) {        Set<ListNode> set = new HashSet<>();        ListNode cur = head;        while(cur!=null){            if(set.contains(cur)){                return cur;            }            set.add(cur);            cur = cur.next;        }        return null;    }}
//方法二:快慢指针

10. 复制带随机指针的链表

// leetcode 138 图解的方法三class Solution {    public Node copyRandomList(Node head) {        if(head==null){            return null;        }        Node cur = head;        while(cur != null){   // 复制出来A->A'->B->B'->C->C',此时的A',B',C'random指针是空            Node temp = new Node(cur.val);            temp.next = cur.next;            cur.next = temp;            cur = temp.next;        }        Node old_head = head;        Node new_head = head.next;        Node old_cur =  old_head;        while(old_cur!=null){//给random指针赋值,A'的random=A的random的next            Node random = old_cur.random;            if(random == null){                old_cur.next.random = null;            }else{                old_cur.next.random = random.next;            }            old_cur = old_cur.next.next;        }        Node cur_1 =  old_head;//截断成两个链表A->B->C 和A'->B'->C'        Node cur_2 =  new_head;        while(cur_2!=null){            if(cur_2.next==null){                cur_1.next = null;            }else{                cur_1.next = cur_2.next;                cur_2.next = cur_2.next.next;            }            cur_1 = cur_1.next;            cur_2 = cur_2.next;        }        return new_head;    }}