建议:了解一下链接基础,以及链表和数组的区别
文章链接:https://programmercarl.com/%E9%93%BE%E8%A1%A8%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html
removeElements
方法的作用是移除链表中指定值的节点,并返回移除后的链表头节点。使用该方法可以轻松地在链表中删除指定值的节点。
该方法接受两个参数:
head
:链表的头节点。val
:要移除的节点的值。使用方法如下:
ListNode node1 = new ListNode(1);
ListNode node2 = new ListNode(2);
ListNode node3 = new ListNode(6);
ListNode node4 = new ListNode(3);
ListNode node5 = new ListNode(4);
ListNode node6 = new ListNode(5);
ListNode node7 = new ListNode(6);
node1.next = node2;
node2.next = node3;
node3.next = node4;
node4.next = node5;
node5.next = node6;
node6.next = node7;
ListNode head = node1;
removeElements
方法,移除链表中值为 6 的节点。head = removeElements(head, 6);
while (head != null) {
System.out.print(head.val + " ");
head = head.next;
}
// 输出:1 2 3 4 5
完整代码如下:
public class Solution {
public static void main(String[] args) {
ListNode node1 = new ListNode(1);
ListNode node2 = new ListNode(2);
ListNode node3 = new ListNode(6);
ListNode node4 = new ListNode(3);
ListNode node5 = new ListNode(4);
ListNode node6 = new ListNode(5);
ListNode node7 = new ListNode(6);
node1.next = node2;
node2.next = node3;
node3.next = node4;
node4.next = node5;
node5.next = node6;
node6.next = node7;
ListNode head = node1;
head = removeElements(head, 6);
while (head != null) {
System.out.print(head.val + " ");
head = head.next;
}
}
public static ListNode removeElements(ListNode head, int val) {
if (head == null) {
return head;
}
head.next = removeElements(head.next, val);
return head.val == val ? head.next : head;
}
}
class ListNode {
int val;
ListNode next;
public ListNode(int val) {
this.val = val;
}
}
题目链接/文章讲解/视频讲解::https://programmercarl.com/0203.%E7%A7%BB%E9%99%A4%E9%93%BE%E8%A1%A8%E5%85%83%E7%B4%A0.html
首先,我们定义了一个名为 removeElements
的方法,它接受两个参数:head
是链表的头节点,val
是要移除的节点的值。
在方法的开始,我们首先检查头节点是否为空。如果为空,说明链表已经遍历完毕,直接返回头节点即可。
接着,我们对链表的下一个节点调用递归方法 removeElements(head.next, val)
,这样就能移除链表中除头节点以外的所有指定值的节点。
然后,我们判断当前头节点的值是否等于目标值 val
。如果等于,说明需要移除该节点,我们将头节点的下一个节点作为新的头节点返回。如果不等于,说明当前头节点不需要移除,直接返回头节点。
最终,当递归回溯到最初的调用时,我们就能得到移除指定值后的链表。
这段代码的核心思想是通过递归来遍历链表,并根据节点的值判断是否需要移除该节点。
// 递归
public ListNode removeElements(ListNode head, int val) {
if (head == null) {
return head;
}
head.next = removeElements(head.next, val);
return head.val == val ? head.next :head;
}
创建一个虚拟头节点 dummyHead
,将其指向原链表的头节点 head
,并创建一个临时节点 temp
,将其指向虚拟头节点。
遍历链表,对于每个节点,判断其值是否等于指定值 val
。
如果节点的值等于 val
,则将该节点从链表中移除。
如果节点的值不等于 val
,则继续遍历链表。
返回虚拟头节点的下一个节点,即移除指定值后的链表头节点。
// 迭代
public ListNode removeElementsIteration(ListNode head, int val) {
ListNode dummyHead = new ListNode(0);
dummyHead.next = head;
ListNode temp = dummyHead;
while (temp.next != null) {
if( temp.next.val == val) {
temp.next = temp.next.next;
} else {
temp = temp.next;
}
}
return dummyHead.next;
}
题目链接/文章讲解/视频讲解:https://programmercarl.com/0707.%E8%AE%BE%E8%AE%A1%E9%93%BE%E8%A1%A8.html
完整代码
class MyLinkedList {
// 定义链表节点类
class ListNode {
int val;
ListNode next;
public ListNode(int val) {
this.val = val;
}
}
private ListNode head; // 链表头节点
private int size; // 链表大小
/** Initialize your data structure here. */
public MyLinkedList() {
head = null;
size = 0;
}
/** Get the value of the index-th node in the linked list. If the index is invalid, return -1. */
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;
}
/** 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) {
ListNode newNode = new ListNode(val);
newNode.next = head;
head = newNode;
size++;
}
/** Append a node of value val to the last element of the linked list. */
public void addAtTail(int val) {
if (head == null) {
addAtHead(val);
return;
}
ListNode cur = head;
while (cur.next != null) {
cur = cur.next;
}
cur.next = new ListNode(val);
size++;
}
/** 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) {
if (index > size) {
return;
}
if (index <= 0) {
addAtHead(val);
return;
}
if (index == size) {
addAtTail(val);
return;
}
ListNode cur = head;
for (int i = 0; i < index - 1; i++) {
cur = cur.next;
}
ListNode newNode = new ListNode(val);
newNode.next = cur.next;
cur.next = newNode;
size++;
}
/** Delete the index-th node in the linked list, if the index is valid. */
public void deleteAtIndex(int index) {
if (index < 0 || index >= size) {
return;
}
if (index == 0) {
head = head.next;
size--;
return;
}
ListNode cur = head;
for (int i = 0; i < index - 1; i++) {
cur = cur.next;
}
cur.next = cur.next.next;
size--;
}
}
题目链接/文章讲解/视频讲解:https://programmercarl.com/0206.%E7%BF%BB%E8%BD%AC%E9%93%BE%E8%A1%A8.html
// 双指针
class Solution {
public ListNode reverseList(ListNode head) {
ListNode prev = null;
ListNode cur = head;
ListNode temp = null;
while (cur != null) {
temp = cur.next;// 保存下一个节点
cur.next = prev;
prev = cur;
cur = temp;
}
return prev;
}
}
// 递归
class Solution {
public ListNode reverseList(ListNode head) {
return reverse(null, head);
}
private ListNode reverse(ListNode prev, ListNode cur) {
if (cur == null) {
return prev;
}
ListNode temp = null;
temp = cur.next;// 先保存下一个节点
cur.next = prev;// 反转
// 更新prev、cur位置
// prev = cur;
// cur = temp;
return reverse(cur, temp);
}
}