LeetCode-链表

本文主要介绍了链表的基础知识和在LeetCode中的常见问题,包括链表的创建、添加、删除等操作,并详细讲解了多个链表题目,如查找链表交点、合并有序链表、反转链表、删除链表节点等,涵盖多种解题思路和代码实现。
摘要由CSDN通过智能技术生成

一、链表基础

1.链表基础知识

参考网址:https://leetcode-cn.com/explore/learn/card/linked-list/

2.设计链表

函数实现的功能
  get(index):获取链表中第 index 个节点的值。如果索引无效,则返回-1。
  addAtHead(val):在链表的第一个元素之前添加一个值为 val 的节点。插入后,新节点将成为链表的第一个节点。
  addAtTail(val):将值为 val 的节点追加到链表的最后一个元素。
  addAtIndex(index,val):在链表中的第 index 个节点之前添加值为 val 的节点。如果 index 等于链表的长度,则该节点将附加到链表的末尾。如果 index 大于链表长度,则不会插入节点。
  deleteAtIndex(index):如果索引 index 有效,则删除链表中的第 index 个节点。

示例
  MyLinkedList linkedList = new MyLinkedList();
  linkedList.addAtHead(1);
  linkedList.addAtTail(3);
  linkedList.addAtIndex(1,2); //链表变为1-> 2-> 3
  linkedList.get(1); //返回2
  linkedList.deleteAtIndex(1); //现在链表是1-> 3
  linkedList.get(1); //返回3
具体设计代码如下

class MyLinkedList {
   
    ListNode head = null;

    /** Initialize your data structure here. */
    public MyLinkedList() {
   

    }
    
    /** Get the value of the index-th node in the linked list. If the index is invalid, return -1. */
    public int get(int index) {
       //获取index索引的节点值
        int i=0;
        while(head != null){
   
            if(index == i){
   
                return head.val;
            }
            else {
   
                head = head.next;
                i++;
            }
        }
        return -1;
    }
    
    /** Add a node of value val before the first element of the linked list. After the insertion, the new node will be the first node of the linked list. */
    public void addAtHead(int val) {
      //添加头节点
        if(head == null){
   
            head = new ListNode(val);
        }
        else {
   
            head.next = new ListNode(val);          
        }

    }
    
    /** Append a node of value val to the last element of the linked list. */
    public void addAtTail(int val) {
      //添加尾结点
        ListNode cur = head;
        while(cur.next != null){
   
            cur = cur.next;
        }
        cur.next = new ListNode(val);
    }
    
    /** Add a node of value val before the index-th node in the linked list. If index equals to the length of linked list, the node will be appended to the end of linked list. If index is greater than the length, the node will not be inserted. */
    public void addAtIndex(int index, int val) {
      //在指定索引处添加节点
        int i=0;
        ListNode cur = head;
        ListNode p = null;
        while(cur != null){
   
            if((index - 1) == -1){
   
                addAtHead(val);
            }
            else if((index - 1) == i){
   
                p = cur.next;
                cur.next = new ListNode(val);
                cur.next.next = p;
            }
            else if((index - 2) == i){
   
                addAtTail(val);
            }
            i++;
            cur = cur.next;
        }
    }
    
    /** Delete the index-th node in the linked list, if the index is valid. */
    public void deleteAtIndex(int index) {
      //删除指定索引的节点
        int i=0;
        ListNode cur = head;
        ListNode pre = null;
        while(cur != null){
   
            if(i == (index - 1)){
   
                pre = cur;
                cur = cur.next;
                pre.next = cur.next;
            }
            i++;
            cur = cur.next;
        }
    }
}

二、链表题(LeetCode)

1.找出两个链表的交点

1) 题目描述
在这里插入图片描述
2) 解题思路:由于创建链表也是创建对象,所以存放在堆内存中,而"=="比较的是对象的内存地址,所以对于某两个节点的值相同并且下一个节点相同,但不一定是交点,因为它们的内存地址不同,不算是同一个节点。
3)代码

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
   
        if(headA == null || headB == null) 
            return null;
        ListNode pA = headA, pB = headB;
        while(pA != pB) {
   
            pA = pA == null ? headB : pA.next;
            pB = pB == null ? headA : pB.next;
        }
        return pA;
    }

leetcode版本:链表交点

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
   
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
   
        ListNode p1 = headA;
        ListNode p2 = headB;
        int flag = 0;
        while(p1 != null && p2 != null && flag <= 2){
   
            if(p1 == p2)
                return p1;
            p1 = p1.next;
            p2 = p2.next;
            if(p1 == null){
   
                p1 = headB;
                flag++;
            }         
            if(p2 == null){
   
                p2 = headA;
                flag++;
            } 
        }
        return null;
    }
}

2.合并两个有序链表

题目链接:合并两个有序链表

1)题目描述
将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
在这里插入图片描述
2) 解题思路
首先,创建的链表节点对象在堆内存中,并且节点之间不一定是占据连续内存,而是节点之间存在单向引用的关系。另外,只有代码new ListNode();是在堆内存中开辟空间从而创建节点,而ListNode p 则定义的是一个应用。这里使用头插法,首先创建一个头节点(这里为节点-1),然后创建相应类型的引用result指向头节点,再让引用p指向头节点,(这里的p和result都可以使用头节点的内容,比如使用p.val,p.next = l1等,可以直接修改,如例1),此时在l1和l2都不为空的情况下,比较l1与l2的值,若l1.val < l2.val,则让p的下一个节点,同时也是result引用指向的节点(即头节点)的下一个节点为l1,然后p指向p.next,此时p指向头节点的下一个节点;若l1.val > l2.val,原理相同。最后l1和l2其中有一个变为null了,此时未变为null的一串节点需要直接加到链表末端,所以让p.next = 剩下的非空链表,最后去掉头节点,返回result得到合并后的链表。
例1:
在这里插入图片描述
3)代码

class Solution {
   
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
   
        ListNode result = new ListNode(-1);   //设置一个头节点(在后面将会去掉)
        ListNode p = result;
        while(l1 != null && l2 != null){
   
            if(l1.val < l2.val){
   
                p.next = l1;
                p = p.next;
                l1 = l1.next;
            }
            else {
   
                p.next = l2;
                p = p.next;
                l2 = l2.next;
            }
        }
            
        if(l1 == null){
   
            p.next = l2;
        }
        else if(l2 == null){
   
            p.next = l1;
        }
        
        result = result.next;  //去掉头节点
        return result;
    }
}

3.反转一个单链表(Easy,题号:206)

第2次
题目链接:反转一个单链表
题目描述
反转一个单链表。
在这里插入图片描述
解题思路

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值