“玩转链表”第一弹(算法 NO.3)
共 2928字,需浏览 6分钟
·
2020-08-10 18:01
本文所列题目来自 LeetCode 中国网站,属于算法面试中关于链表的经典高频考题(“玩转链表”第一弹)。题解由 Doocs 开源社区 leetcode 项目维护者提供。
目前已经有超过 50 位开发者参与了此项目,期待你的加入!
项目地址:https://github.com/doocs/leetcode
题目 1
题目描述
从尾到头打印链表 。
输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。
示例 1:
输入:head = [1,3,2]
输出:[2,3,1]
限制:
•0 <= 链表长度 <= 10000
解法
栈实现。
Python3
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def reversePrint(self, head: ListNode) -> List[int]:
res = []
while head:
res.append(head.val)
head = head.next
return res[::-1]
Java
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public int[] reversePrint(ListNode head) {
Stack<Integer> s = new Stack<>();
while (head != null) {
s.push(head.val);
head = head.next;
}
int[] res = new int[s.size()];
int i = 0;
while (!s.isEmpty()) {
res[i++] = s.pop();
}
return res;
}
}
题目 2
题目描述
删除链表的节点。
给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。
返回删除后的链表的头节点。
注意:此题对比原题有改动
示例 1:
输入: head = [4,5,1,9], val = 5
输出: [4,1,9]
解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9.
示例 2:
输入: head = [4,5,1,9], val = 1
输出: [4,5,9]
解释: 给定你链表中值为 1 的第三个节点,那么在调用了你的函数之后,该链表应变为 4 -> 5 -> 9.
说明:
•题目保证链表中节点的值互不相同•若使用 C 或 C++ 语言,你不需要 free
或 delete
被删除的节点
解法
定义一个虚拟头节点 dummy
指向 head
,再定义指针 pre
和 p
分别指向 dummy
和 head
。
遍历链表,pre
、p
往后移动。当指针 p
指向的节点的值等于 val
时,将 pre.next
指向 p.next
,然后返回 dummy.next
。
Python3
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def deleteNode(self, head: ListNode, val: int) -> ListNode:
dummy = ListNode(0)
dummy.next = head
pre, p = dummy, head
while p:
if p.val == val:
pre.next = p.next
break
pre, p = p, p.next
return dummy.next
Java
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode deleteNode(ListNode head, int val) {
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode pre = dummy, p = head;
while (p != null) {
if (p.val == val) {
pre.next = p.next;
break;
}
pre = p;
p = p.next;
}
return dummy.next;
}
}
题目 3
题目描述
链表中倒数第 k 个节点。
输入一个链表,输出该链表中倒数第 k 个节点。为了符合大多数人的习惯,本题从 1 开始计数,即链表的尾节点是倒数第 1 个节点。例如,一个链表有 6 个节点,从头节点开始,它们的值依次是 1、2、3、4、5、6。这个链表的倒数第 3 个节点是值为 4 的节点。
示例:
给定一个链表: 1->2->3->4->5, 和 k = 2.
返回链表 4->5.
解法
定义 p
、q
指针指向 head
。
p
先向前走 k
步,接着 p
、q
同时向前走,当 p
指向 null
时,q
指向的节点即为链表的倒数第 k
个节点。
Python3
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def getKthFromEnd(self, head: ListNode, k: int) -> ListNode:
if not (head or head.next):
return head
p = q = head
for _ in range(k):
p = p.next
while p:
p = p.next
q = q.next
return q
Java
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode getKthFromEnd(ListNode head, int k) {
if (head == null || head.next == null) {
return head;
}
ListNode p = head, q = head;
while (k-- > 0) {
p = p.next;
}
while (p != null) {
p = p.next;
q = q.next;
}
return q;
}
}
题目 4
题目描述
反转链表。
定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
限制:
•0 <= 节点个数 <= 5000
解法
定义指针 p
、q
分别指向头节点和下一个节点,pre
指向头节点的前一个节点。
遍历链表,改变指针 p
指向的节点的指向,将其指向 pre
指针指向的节点,即 p.next = pre
。然后 pre
指针指向 p
,p
、q
指针往前走。
当遍历结束后,返回 pre
指针即可。
Python3
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
pre, p = None, head
while p:
q = p.next
p.next = pre
pre = p
p = q
return pre
Java
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
ListNode pre = null;
ListNode p = head;
while (p != null) {
ListNode q = p.next;
p.next = pre;
pre = p;
p = q;
}
return pre;
}
}
长按识别下图二维码,关注公众号「Doocs 开源社区」,第一时间跟你们分享好玩、实用的技术文章与业内最新资讯。