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)
建立模型:
- 移除非头节点:通过前一节点的next属性指向被移除节点的next节点即
pre.next = cur.next - 移除头节点:直接将head后移一位即
head = head.next - 为了统一上面两种操作,创建一个虚拟头节点,其next属性指向head,这样所有节点的移除都被归类为非头节点
- 返回虚拟头节点的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位置的节点
建立模型:
- 考虑使用单链表实现
- 需要初始化头节点和链表长度
- 按功能添加代码
代码实现:
# 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)
建立模型:
- 定义两个指针 previous=head,current=head.next
- 将current指针的next节点保存在temp中
- 翻转previous,current的前后关系
- 更新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)
建立模型:
- 定义两个指针 previous=virtual_head,current=head
- 将要与current交换的节点保存在following中
- 交换两个相邻的节点
- 更新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链表问题(一)的更多相关文章
- insertion Sort List (链表的插入排序) leecode java
逻辑简单,代码难写,基础不劳,leecode写注释不能出现中文,太麻烦,我写了大量注释,链表问题最重要的就是你那个指针式干啥的 提交地址https://oj.leetcode.com/problems ...
- leecode 归并排序 链表(java)
写了好久,终于写成了.第一次zai leecode错题,题目质量很高,适合面试,与 1.归并排序是稳定的,在java中 Arrays.sort(a);中对于对象的排序就是归并排序.对于原子类型数据使用 ...
- leecode刷题(21)-- 删除链表的倒数第N个节点
leecode刷题(21)-- 删除链表的倒数第N个节点 删除链表的倒数第N个节点 描述: 给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点. 示例: 给定一个链表: 1->2- ...
- leecode刷题(20)-- 删除链表中的节点
leecode刷题(20)-- 删除链表中的节点 删除链表中的节点 描述: 请编写一个函数,使其可以删除某个链表中给定的(非末尾)节点,你将只被给定要求被删除的节点. 现有一个链表 -- head = ...
- leecode 刷题(32)-- 链表的中间节点
leecode 刷题(32)-- 链表的中间节点 描述: 给定一个带有头结点 head 的非空单链表,返回链表的中间结点. 如果有两个中间结点,则返回第二个中间结点. 示例 1: 输入:[1,2,3, ...
- leecode刷题(27)-- 合并k个排序链表
leecode刷题(27)-- 合并k个排序链表 合并k个排序链表 合并 k 个排序链表,返回合并后的排序链表.请分析和描述算法的复杂度. 示例: 输入: [ 1->4->5, 1-> ...
- leecode刷题(23)-- 合并两个有序链表
leecode刷题(23)-- 合并两个有序链表 合并两个有序链表 将两个有序链表合并为一个新的有序链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. 示例: 输入:1->2-> ...
- leecode第一百四十八题(排序链表)
class Solution { public: void sort_list(ListNode* head1, ListNode* head2,int len)//在原链表上进行排序 { ListN ...
- leecode第六十一题(旋转链表)
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode ...
- leecode第二十三题(合并K个排序链表)
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode ...
随机推荐
- Excel 多表头导入导出(借助Aspose)
需求中Excell多表头,完成导入导出. Aspose 代码实现多表头方式借助代码比较繁琐, 借助模板方式. 简化逻辑. 注意,aspose从0开始索引. 导入部分代码: 实现选择导入Excel,导入 ...
- [C#]接口Interface快速Demo
参考代码1: using System; namespace InterfaceDemo { /// <summary> /// 定义一个爬树接口 /// </summary> ...
- Angular架构学习
定义 Angular 是一个用 HTML 和 JavaScript 或者一个可以编译成 JavaScript 的语言(例如 Dart 或者 TypeScript ),来构建客户端应用的框架. 写 An ...
- 无法将类 org.example.sh.utils.PageInfo<T>中的构造器 PageInfo应用到给定类型;
是因为没有在工具类中加入构造器, @Data @NoArgsConstructor @AllArgsConstructor @ToString
- 深入理解css 笔记(9)
模块化 CSS 是指把页面分割成不同的组成部分,这些组成部分可以在多种上下文中重复使用,并且互相之间没有依赖关系.最终目的是,当我们修改其中一部分 css 时,不会对其他部分产生意料之外的影响. ...
- 导出生成word
用XML做就很简单了.Word从2003开始支持XML格式,大致的思路是先用office2003或者2007编辑好word的样式,然后另存为xml,将xml翻译为FreeMarker模板(后缀为.ft ...
- OSPF之路由撤销
- JDK8:Lambda表达式操作List集合
JDK8的流对list的处理提供了很大的方便,特别是做报表的时候才能真正体现出来这个功能的强大:结合日常使用过程,有两个体会:一个是减少了数据库连接,最忌讳在循环中进行数据查询,特别是嵌套多层循环的时 ...
- 漫谈Python魔术方法,见过的没见过的都在这里了
漫谈Python魔术方法,见过的没见过的都在这里了 就说一下,不深入 假的一览 提到魔术方法,学过python都应该知道一些.至少你得会__init__吧. 在我之前写的博文中有很多都涉及魔术方法.比 ...
- VSCode使用小技巧
VSCode写C/C++项目 我们需要先下载minGW,并需要在VS Code里面下载相应的插件, 如下: 然后,将vscode保存c++项目的文件夹用vscode打开,就会出现这样的形式: 一个标准 ...