203.移除链表元素
题目链接/文章讲解/视频讲解::programmercarl.com/0203.%E7%A7…
思路
本题是链表的基础操作之一,链表删除操作关键步骤在于,通过绕过节点再删除该节点内存的方式达到删除的效果。Java有自带的回收机制,所以删除节点内存可以忽略。同时,删除头节点和删除中间节点的方法是不一样的,如果删除的是头节点,那就没有前序节点,无法进行“绕过”的操作。此时有两种方法,一种是单独判断是否是删除头节点,另一种是使用虚拟头节点让所有的节点都成为非头节点,从而达到结果。在这里我选用虚拟头节点的方式。
/**
* 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; }
* }
*/
class Solution {
public ListNode removeElements(ListNode head, int val) {
if(head == null){
return head;
}
ListNode dummyHead = new ListNode(-1, head);
ListNode pre = dummyHead;
ListNode cur = dummyHead.next;
while(cur != null)
{
if(cur.val == val){
pre.next = cur.next;
}else{
pre = cur;
}
cur = cur.next;
}
return dummyHead.next;
}
}
707.设计链表
题目链接/文章讲解/视频讲解:programmercarl.com/0707.%E8%AE…
思路
class LinkedNode{
int val;
LinkedNode next;
public LinkedNode(){};
public LinkedNode(int val){this.val = val;}
}
class MyLinkedList {
private int size;
private LinkedNode dummyHead;
public MyLinkedList() {
size = 0;
dummyHead = new LinkedNode(-1);
}
public int get(int index) {
if (index < 0 || index >= size) return -1;
LinkedNode cur = dummyHead.next;
for (int i = 0; i < index; i++) {
cur = cur.next;
}
return cur.val;
}
// 可以直接调用addAtIndex
// public void addAtHead(int val) {
// addAtIndex(0, val);
// }
public void addAtHead(int val) {
LinkedNode newHead = new LinkedNode(val);
newHead.next = dummyHead.next;
dummyHead.next = newHead;
size++;
}
// 可以直接调用addAtIndex
// public void addAtTail(int val) {
// addAtIndex(size, val);
// }
public void addAtTail(int val) {
LinkedNode node = new LinkedNode(val);
LinkedNode cur = dummyHead;
while(cur.next != null)
{
cur = cur.next;
}
cur.next = node;
size++;
}
public void addAtIndex(int index, int val) {
if(index > size) return;
if(index < 0) index = 0;
LinkedNode pre = dummyHead;
for(int i = 0; i < index; i++){
pre = pre.next;
}
LinkedNode node = new LinkedNode(val);
node.next = pre.next;
pre.next = node;
size++;
}
public void deleteAtIndex(int index) {
if (index < 0 || index >= size) return;
LinkedNode pre = dummyHead;
for (int i = 0; i < index; i++) {
pre = pre.next;
}
if (pre.next != null) {
pre.next = pre.next.next;
}
size--;
}
}
/**
* Your MyLinkedList object will be instantiated and called as such:
* MyLinkedList obj = new MyLinkedList();
* int param_1 = obj.get(index);
* obj.addAtHead(val);
* obj.addAtTail(val);
* obj.addAtIndex(index,val);
* obj.deleteAtIndex(index);
*/
206.反转链表
题目链接/文章讲解/视频讲解:programmercarl.com/0206.%E7%BF…
思路
理解反转链表的核心是,如何改变每个节点的指向,即当前节点指向它之前的节点。开始时,我们有一个指向链表头部的指针cur。在反转过程中,我们逐个访问这个链表的每个节点,并将每个节点的next指针指向它的前一个节点。为了遍历这个链表,我们还需要额外引入一个temp节点,用于存储还未遍历的链表。整个过程就是在不断地更新节点间的连接关系,直到所有节点都重新指向了它们之前的节点。反转完成后,我们得到一个新的链表,其节点顺序与原始链表完全相反。这个过程不涉及新节点的创建,仅仅是改变现有节点间的连接方式。
代码随想录的动图更加直观:
class Solution {
public ListNode reverseList(ListNode head) {
ListNode prev = null;
ListNode cur = head;
ListNode tmp = null;
while(cur != null)
{
tmp = cur.next;
cur.next = prev;
prev = cur;
cur = tmp;
}
return prev;
}
}