移除链表元素
题目链接: 203. 移除链表元素 - 力扣(LeetCode)
解题思路:
要设置虚拟头结点,这样如果移除的结点是头结点head,包括后序对链表的操作,都可以对所有的结点一视同仁,也不用分类讨论( 该节点是否是头结点).
接下来声明两个遍历ListNode pre和 curr,初始值为 dummy 和head.
遍历链表,遇到结点值等于 目标值val的时候,让该节点的前一个结点pre的指针指向 当前结点的下一个结点 pre.next=curr.next.
最后返回dummy 的下一个结点 ( 就是头结点 ),而不是head,head也可能被删除掉.
答案:
class Solution {
public ListNode removeElements(ListNode head, int val) {
ListNode dummy=new ListNode(-1,head) ;
ListNode pre=dummy;
ListNode curr=head;
while (curr!=null ){
if (curr.val==val){
pre.next=curr.next;
}else {
pre=curr;
}
curr=curr.next;
}
return dummy.next;
}
}
● 707.设计链表
题目链接: 707. 设计链表 - 力扣(LeetCode)
解题思路:
需要自己创建一个单向链表 或者双向链表对象. 本答案为 单向链表.
对链表进行初始化,size这块的设置没有想到. 包括后面增加和删除的时候,分别size++ 和size--.都没有考虑到. 还要初始化虚拟头结点dummy.
get(index):
获取元素是比较容易的. 遍历到index位置处,返回对应值.
addAtIndex(index,val):
添加元素的时候,容易出错.
遍历到索引等于index 的结点的前一个结点 pre.
先让新增结点 listNode ( 值为val ) 指向 pre的下一个结点. 再让pre指向 新增结点 listNode.
ListNode listNode = new ListNode(val);
listNode.next=pre.next;
pre.next=listNode;
deleteAtIndex(index):
pre.next= pre.next.next;
遍历到索引等于index 的前一个位置, 让前一个位置pre 的指针指向 索引等于 index的位置的结点 pre.next 的下一个结点,就完成了删除.
参考答案:
class ListNode {
ListNode next;
int val;
public ListNode() {
}
public ListNode( int value,ListNode next) {
this.next = next;
this.val = value;
}
public ListNode(int value) {
this.val = value;
}
}
class MyLinkedList {
// 链表长度 和 虚拟头结点
private int size;
private ListNode dummy;
public MyLinkedList() {
dummy = new ListNode(-1);
size = 0;
}
public int get(int index) {
if (index >= size || index < 0) {
return -1;
}
ListNode pre = dummy;
for (int i = 0; i <= index; i++) {
pre = pre.next;
}
return pre.val;
}
public void addAtHead(int val) {
addAtIndex(0, val);
}
public void addAtTail(int val) {
addAtIndex(size, val);
}
public void addAtIndex(int index, int val) {
if (index < 0) {
index = 0;
}
if (index > size) {
return;
}
size++;
ListNode pre = dummy;
for (int i = 0; i <index; i++) {
pre = pre.next;
}
ListNode listNode = new ListNode(val);
listNode.next=pre.next;
pre.next=listNode;
}
public void deleteAtIndex(int index) {
if (index >= size || size < 0) {
return ;
}
size--;
ListNode pre = dummy;
for (int i = 0; i < index; i++) {
pre = pre.next;
}
pre.next= pre.next.next;
}
}
● 206.反转链表
题目链接: https://leetcode.cn/problems/reverse-linked-list/
解题思路:
此题不能设置虚拟头结点,否则反转之后,链表多了一个结点.
通过设置三个结点来实现, ListNode pre ; curr ; temp
ListNode pre = null;
ListNode curr = head;
ListNode temp = null;
循环内容:
tem结点用来临时存储 curr,next;
完成curr和 pre的指针反向关系. curr.next=pre; (curr左指向右,变成右指向左.)
接下来, pre和 curr各向前移动一个位置.
pre=curr;
curr=temp;
while循环结束,返回的头结点head 是谁呢? curr为null的时候,遍历到链表的尾部了,不能for循环了,所以返回的是curr的前一位 pre.

参考答案:
class Solution {
public ListNode reverseList(ListNode head) {
if (head == null) {
return null;
}
ListNode pre = null;
ListNode curr = head;
ListNode temp = null;
while (curr != null) {
temp = curr.next;
curr.next=pre;
pre=curr;
curr=temp;
}
return pre;
}
}