LeeCode链表问题(一)

2022/6/24 23:21:44

本文主要是介绍LeeCode链表问题(一),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

本文中所使用的链表定义如下所示:

# Definition for singly-linked list.
class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next
// Definition for singly-linked list.
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; }
}

LeeCode 203: 移除链表元素

题目描述:

给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回新的头节点

标签: 链表,递归

时间复杂度:O(N)

建立模型:

  1. 移除非头节点:通过前一节点的next属性指向被移除节点的next节点即 pre.next = cur.next
  2. 移除头节点:直接将head后移一位即 head = head.next
  3. 为了统一上面两种操作,创建一个虚拟头节点,其next属性指向head,这样所有节点的移除都被归类为非头节点
  4. 返回虚拟头节点的next域

代码实现:

# Python3 实现
def removeElement(self, head: ListNode, val: int) -> ListNode:
    virtual_head = ListNode(val=0, next=head)
    pre, cur = virtual_head, head

    while cur is not None:
        if cur.val == val:
            pre.next = cur.next
        else:
            pre = cur
        cur = cur.next

    return virtual_head.next
// Java 实现
public ListNode removeElements(ListNode head, int val) {
  ListNode virtualHead = new ListNode(0, head);
  ListNode pre = virtualHead;
  ListNode cur = head;
  
  while (cur != null) {
    if (cur.val == val)
      pre.next = cur.next;
    else
      pre = cur;
    cur = cur.next;
  }
  return virtualHead.next;
}

LeeCode 707: 设计链表

题目描述:

设计链表的实现,可以选择使用单链表或双链表。单链表中的节点应该具有两个属性:val 和 next。val 是当前节点的值,next 是指向下一个节点的指针/引用。如果要使用双向链表,则还需要一个属性 prev 以指示链表中的上一个节点。假设链表中的所有节点都是 0-index 的。

在链表中实现这些功能:

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

建立模型:

  1. 考虑使用单链表实现
  2. 需要初始化头节点和链表长度
  3. 按功能添加代码

代码实现:

# Python3 实现
class MyLinkedList:
    def __init__(self):
        self.size = 0
        self.head = None
    
    def get(self, index: int) -> int:
        if index >= self.size:
            return -1
        temp = self.head
        for _ in range(index):
            temp = temp.next
        return temp.val
    
    def addAtHead(self, val: int) -> None:
        node = ListNode(val, None)
        if self.head is None:
            self.head = node
        else:
            temp = self.head
            self.head = node
            self.head.next = temp
        self.size += 1
    
    def addAtTail(self, val: int) -> None:
        node = ListNode(val, None)
        if self.head is None:
            self.head = node
        else:
            temp = self.head
            while temp.next:
                temp = temp.next
            temp.next = node
        self.size += 1
    
    def addAtIndex(self, index: int, val: int) -> None:
        if index > self.size:
            print("Add: Index out of range!")
            return
        if index == self.size:
            self.addAtTail(val)
        elif index <= 0:
            self.addAtHead(val)
        else:
            pre = self.head
            for _ in range(index - 1):
                pre = pre.next
            cur = pre.next
            
            # 插入Node
            node = ListNode(val, None)
            pre.next = node
            node.next = cur
            self.size += 1
        return
    
    def deleteAtIndex(self, index: int) -> None:
        if index < 0 or index >= self.size:
            print("Delete: Index out of range!")
            return
        if index == 0:
            self.head = self.head.next
        else:
            pre = self.head
            for _ in range(index - 1):
                pre = pre.next
            cur = pre.next
            
            # 删除cur节点
            pre.next = cur.next
        
        self.size -= 1
        return

LeeCode 206: 反转链表

题目描述:

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

标签:链表,递归

时间复杂度:O(N)

建立模型:

  1. 定义两个指针 previous=head,current=head.next
  2. 将current指针的next节点保存在temp中
  3. 翻转previous,current的前后关系
  4. 更新previous,current指向的节点

代码实现:

# Python3 实现
def reverseList(self, head: ListNode) -> ListNode:
    # 空链表或只有一个节点的链表翻转还是它自己
    if not head or not head.next:
        return head
    
    previous, current = head, head.next
    previous = None
    while current:
        temp = current.next
        current.next = previous
        
        # 更新 previous, current节点
        previous = current
        current = temp
    return previous
// Java 实现
public ListNode reverseList(ListNode head) {
  if (head == null || head.next == null) {
    return head;
  }
  
  ListNode previous = head;
  ListNode current = head.next;
  previous.next = null;
  
  while (current != null) {
    ListNode temp = current.next;
    current.next = previous;
    
    previous = current;
    current = temp;
  }
  
  return previous;
}

LeeCode 24: 两两交换链表中的节点

题目描述:

给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即只能进行节点交换)。

题目解释:

  • 若链表节点个数为偶数,则每两个节点交换即(1, 2), (3, 4), ..., (N-1, N)
  • 若链表节点个数为奇数,则前N-1个节点每两个交换,最后一个节点不交换即(1, 2), (3, 4), ..., (N-2, N-1), (N)

建立模型:

  1. 定义两个指针 previous=virtual_head,current=head
  2. 将要与current交换的节点保存在following中
  3. 交换两个相邻的节点
  4. 更新previous,current节点

代码实现:

# Python3 实现
def swapPairs(self, head: ListNode) -> ListNode:
    virtual_head = ListNode(0, head)
    previous, current = virtual_head, head
    while current and current.next:
        following = current.next
        
        # 交换两个相邻节点
        previous.next = following
        current.next = following.next
        following.next = current
        
        # 更新previous, current节点
        previous = current
        current = current.next
    return virtual_head.next
// Java 实现
public ListNode swapPairs(ListNode head) {
  ListNode virtualHead = new ListNode(0, head);
  ListNode previous = virtualHead;
  ListNode current = head;
  
  while (current != null && current.next != null) {
    ListNode following = current.next;
    
    previous.next = following;
    current.next = following.next;
    following.next = current;
    
    previous = current;
    current = current.next;
  }
  
  return virtualHead.next;
}


这篇关于LeeCode链表问题(一)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程