Leetcode链表

Leetcode链表

一.闲聊

边学边刷的……慢慢写慢慢更

二.题目

1.移除链表元素


题干:

LkQ26J.png


思路:

  • 删除链表节点,就多了一个判断等值。
  • 由于是单向链表,所以要删除节点时要找到目标节点的上一个节点,如果是双向链表,指向要删除节点本身即可
  • 链表的头节点存在着被删除的风险,所以使用虚拟头节点来方便返回

代码:

public class ListNode{
    int val;
    ListNode next;
    ListNode() {}
    ListNode(int val) {this.val=val;}
    ListNode(int val,ListNode next) {this.val=val;this.next=next;}
}
class Soulution{
    public ListNode removeElements(ListNode head,int val){
        //做个特判
        if(head==null){
            return head;
        }
        //以下两句可以用最后的构造器合并成一行。
        ListNode dummy=new ListNode(0);
        dummy.next=head;
        ListNode cur=dummy;
        while(cur.next!=null){
            if(cur.next.val==val){
                cur.next=cur.next.next
            }else{
                cur=cur.next;
            }
        }
        return dummy.next;
    }
}

2.设计链表


题干:

Lkcp1e.png


思路:

  • 一步步顺着实现各个接口即可,长个心眼就是addAtIndex这个功能可以在特殊情况如Head和Tail中进行调用,没必要在两个方法重新编写了。、

代码:

class MyLinkedList {
    int size;
    ListNode head;
    public MyLinkedList() {
        size=0;
        head=new ListNode(0);
    }

    public int get(int index) {
        if(index<0||index>=size){
            return -1;
        }
        ListNode cur=head;
        for(int i=0;i<=index;i++){
            cur=cur.next;
        }
        return cur.val;
    }

    public void addAtHead(int val) {
        addAtIndex(0,val);
    }

    public void addAtTail(int val) {
        addAtIndex(size,val);
    }

    public void addAtIndex(int index, int val) {
        if(index<0){
            index=0;
        }
        if(index>size){
            return;
        }
        size++;
        ListNode listNode=new ListNode(val);
        ListNode cur=head;
        for(int i=0;i<index;i++){
            cur=cur.next;
        }
        listNode.next=cur.next;
        cur.next=listNode;
    }

    public void deleteAtIndex(int index) {
        if(index>=size||index<0){
            return;
        }
        size--;
        ListNode cur=head;
        for(int i=0;i<index;i++){
            cur=cur.next;
        }
        cur.next=cur.next.next;
    }
}

class ListNode{
    int val;
    ListNode next;
    ListNode(){}
    ListNode(int val){
        this.val=val;
    }
}

这道题用了虚拟头节点,也可以理解为哨兵,目的是为了保证链表始终处于非空的状态。 而正由于存在虚拟头节点,所以与传统的链表操作存在不同,但思想一致。比如查找节点的值时,如果不存在虚拟头节点,那么我们循环index次即可,现在要循环index+1次。

3.翻转链表


题干:反转一个单链表。 示例:示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL


思路:

  • 双指针法即可。一前一后配合

代码:

class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode cur=head;
        ListNode pre=null;
        while (cur!=null){
            //将下一个节点保存,否则就找不到下一个了
            ListNode temp=cur.next;
            cur.next=pre;
            pre=cur;
            cur=temp;
        }
        return pre;
    }
}

4.删除链表的倒数第N个节点


题干:

Lkxsat.png


思路:

  • 双指针,一快一慢,快的先走n+1步,保证慢指针最后会指向要删除节点的前一个节点,之后执行普通的删除节点操作即可
  • 这题同样存在着删除头结点的情况,所以使用虚拟头节点方便处理

代码:

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummy=new ListNode(0);
        dummy.next=head;
        ListNode fast=dummy;
        ListNode slow=dummy;
        for(int i=0;i<=n;i++){
            fast=fast.next;
        }
        while (fast!=null){
            fast=fast.next;
            slow=slow.next;
        }
        slow.next=slow.next.next;
        return dummy.next;
    }
}

5.链表相交


题干:

LASdHA.png


思路:

  • 首先遍历第一个链表,其中会产生重复的部分必定不是两链表的相交点,所以可以利用哈希集合去重,并记录下每个节点。之后遍历第二条链表的同时在哈希集合中查找是否存在交集,存在的第一个交集即是链表的交点,之后的所有点都是共同点。

代码:

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        Set<ListNode> set=new HashSet<ListNode>();
        while (headA!=null){
            set.add(headA);
            headA=headA.next;
        }
        while (headB!=null){
            if(set.contains(headB)){
                return headB;
            }
            headB=headB.next;
        }
        return null;
    }
}

6.环形链表II


题干:

LApsaR.png


思路:

  • 与链表相交题目相似,一种解法是同样可以利用哈希集合判断,遍历链表,当出现当前节点的下一节点已经存在于哈希集合当中时,我们就返回当前节点下一节点即可(也可以是当前节点出现在哈希集合中后,返回当前节点)

代码:

public class Solution {
    public ListNode detectCycle(ListNode head) {
        Set<ListNode> set=new HashSet<ListNode>();
        ListNode cur=head;
        while (cur!=null){
            if(set.contains(cur)){
                return cur;
            }else{
                set.add(cur);
            }
            cur=cur.next;
        }
        return null;
    }
}
posted @ 2022-07-16 13:58  Appletree24  阅读(19)  评论(0编辑  收藏  举报