当前位置:   article > 正文

【LeetCode之链表】_leetcode 链表

leetcode 链表

!!~:题目来源链接



1、找出两个链表的交点

在这里插入图片描述
在这里插入图片描述

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        ListNode p=headA,q=headB;
        while (p!=q){
            p= p==null ? headB : p.next;
            q= q==null ? headA : q.next;
        }
        return p;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

2、链表反转

在这里插入图片描述
递归方法(链表中很多题目都可以用递归的思想!)

class Solution{
    public ListNode reverseList(ListNode head) {
    if (head == null || head.next == null) {
        return head;
    }
    ListNode p = head.next;
    ListNode newHead = reverseList(p);
    p.next = head;
    head.next = null;
    return newHead;
   }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

原地逆转,逐个将元素使用头插法插入到新链表中!

class Solution{
    public ListNode reverse(ListNode node){
        if(node==null || node.next==null) return node;
        ListNode pre=new ListNode();
        while (node!=null){
            ListNode next=node.next;
            node.next=pre;
            pre=node;
            node=next;
        }
        return pre;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

3、归并两个有序链表

在这里插入图片描述

class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
     ListNode p=new ListNode(0); //新建并申请空间;
     ListNode q=p;    //用于边遍历边排序
     while(l1!=null && l2!=null){
         if(l1.val<l2.val){
          q.next=l1;
          l1=l1.next;
         }else{
          q.next=l2;
          l2=l2.next;
         }
         q=q.next;
     }
     q.next= (l1==null) ? l2 : l1;
     return p.next;       //p.next其实就是新的链表;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

4、从有序链表中删除重复节点

在这里插入图片描述
在这里插入图片描述
使用递归的方法!

class Solution {
    public ListNode deleteDuplicates(ListNode head) {
        if(head==null || head.next==null) return head;
        head.next=deleteDuplicates(head.next);
        return head.val==head.next.val ? head.next : head;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

5、删除链表中倒数第n个节点

在这里插入图片描述
主要还是涉及到快慢指针,需要注意的是当链表只有两个元素时、n即链表长度时…等一些特殊情况;

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
    ListNode fast = head;
    while (n> 0) {
        fast = fast.next;
        n--;
    }
    if (fast == null) return head.next;  //需要注意这里!!!
    ListNode slow = head;
    while (fast.next != null) {
        fast = fast.next;
        slow = slow.next;
    }
    slow.next = slow.next.next;
    return head;
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

6、交换链表中的相邻节点

在这里插入图片描述
也是一种递归思想,就很…简单Nice。

class Solution {
    public ListNode swapPairs(ListNode head) {
        if(head==null || head.next==null)
            return head;
        ListNode p=head.next;
        head.next=swapPairs(head.next.next);
        p.next=head;
        return p;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

7、链表两数求和

在这里插入图片描述
因为是从链表的尾部计算的,所以要用到Stack!

class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        Stack<ListNode> stack1=new Stack<>();
        Stack<ListNode> stack2=new Stack<>();
        while (l1!=null){
            stack1.push(l1);
            l1=l1.next;
        }
        while (l2!=null){
            stack2.push(l2);
            l2=l2.next;
        }
        int flag=0;
        ListNode newhead=new ListNode(0);
        ListNode s=newhead;
        while (!stack1.isEmpty() || !stack2.isEmpty()){
            ListNode p= !stack1.isEmpty() ? stack1.pop() : null;
            ListNode q= !stack2.isEmpty() ? stack2.pop() : null;
            int a= p!=null ? p.val : 0;   //这个写法很多地方都会用到!
            int b= q!=null ? q.val : 0;
            int num=(a+b+flag)%10;
            flag=(a+b+flag)/10;
            ListNode node=new ListNode(num);
            node.next=s.next;
            s.next=node;
        }
        if(flag!=0){
            ListNode node=new ListNode(flag);
            node.next=s.next;
            s.next=node;
        }
        return newhead.next;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

8、回文链表

在这里插入图片描述
方法一:把所有元素入栈,然后出栈的过程中遍历链表就OK。

class Solution {
    public boolean isPalindrome(ListNode head) {
        Stack<ListNode> stack=new Stack<>();
        ListNode p=head;
        while (p!=null){
            stack.push(p);
            p=p.next;
        }
        p=head;
        while (p!=null){
            if(p.val!=stack.pop().val)
                return false;
            p=p.next;
        }
        return true;

    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

方法二:栈的方法还可以优化一下。

class Solution {
    public boolean isPalindrome(ListNode head) {
        Stack<ListNode> stack=new Stack<>();
        ListNode p=head;
        while (p!=null){
            stack.push(p);
            p=p.next;
        }
        int size=stack.size()/2;
        p=head;
        while (size>0){
            if(p.val!=stack.pop().val)
                return false;
            p=p.next;
            --size;
        }
        return true;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

方法三:快慢指针,将后面半部分逆转,并比较。

class Solution {
    public boolean isPalindrome(ListNode head) {
        ListNode fast=head,slow=head;
        while (fast!=null && fast.next!=null){
            fast=fast.next.next;
            slow=slow.next;
        }
        if(fast!=null)
            slow=slow.next;
        slow=reverse(slow);
        fast=head;
        while (slow!=null){
            if(slow.val!= fast.val)
                return false;
            slow=slow.next;
            fast=fast.next;
        }
        return true;
    }
    //逆转后半部分————这里可以用递归的方法
//    public ListNode reverse(ListNode node){
//        if(node==null || node.next==null) return node;
//        ListNode p=node.next;
//        ListNode newhead=reverse(p);
//        p.next=node;
//        node.next=null;
//        return p;
//    }
    //反转链表的另一种方法
    public ListNode reverse(ListNode node){
        if(node==null || node.next==null) return node;
        ListNode pre=null;  //注意这里为null,还是新建一个new ListNode(0)是不一样的。
        while (node!=null){
            ListNode next=node.next;
            node.next=pre;
            pre=node;
            node=next;
        }
        return pre;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

9、分隔链表

在这里插入图片描述
在这里插入图片描述
看似复杂其实蛮简单的,主要是要计算出有几个“特殊组”,这些“特殊组”比其他普通组的多一个。

class Solution {
    public ListNode[] splitListToParts(ListNode head, int k) {
        int len=0;
        ListNode p=head;
        while (p!=null){
            len++;
            p=p.next;
        }
        int m=len%k; //前m个
        int n=len/k; //每个有几个
        int curlen=0;
        ListNode[] res=new ListNode[k];
        for(int i=0;i<k;++i){
            ListNode newhead=new ListNode();
            newhead.next=head;
            p=newhead;
            if(m>0)
                curlen=n+1;
            else curlen=n;
            while (curlen>0){
                head=head.next;
                p=p.next;
                --curlen;
            }
            if(p!=null) p.next=null;
            --m;
            res[i]=newhead.next;
        }
        return res;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

10、链表元素按奇偶聚集

在这里插入图片描述
在这里插入图片描述
关键在于要记住“oddend”奇链最后一个,以及"evenend"偶链的最后一个。

class Solution {
    public ListNode oddEvenList(ListNode head) {
        if(head==null || head.next==null || head.next.next==null) return head;
        ListNode oddend=head,evenend=head.next;
        while (evenend!=null && evenend.next!=null){
            ListNode p=evenend.next;
            evenend.next=p.next;
            p.next=oddend.next;
            oddend.next=p;
            oddend=oddend.next;
            evenend=evenend.next;
        }
        return head;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

总结

1、递归是个好方法,链表中很多问题都可以用递归去解决!
2、注意一些特殊情况,即只有一个或两个元素等!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/618099
推荐阅读
相关标签
  

闽ICP备14008679号