移除链表元素 需要进行链表的遍历找到该节点;当该结点是头结点时由于要返回头节点不能直接删除创建一个新节点指向头节点作为虚拟头节点并返回;该节点是尾节点时只需将上一结点next设为null;节点是中间节点将上一next=pre.next.next指针指向下一节点;
class Solution {
public ListNode removeElements(ListNode head, int val) {
ListNode hea=new ListNode();//创建新结点
hea.next=head;//节点作为新的头节点在头节点值也为val时也能删除
ListNode pre=hea;//新的链表
while(pre.next!=null){
if(pre.next.val==val){
pre.next=pre.next.next;//指针指向下一节点
}else{
pre=pre.next;//遍历
}
}
return hea.next;
}
}
设计链表 初始化一个链表进行链表的遍历,结点的添加与删除,在插入时头结点尾结点与中间节点有所区别,有的需要遍历有的不需要,在进行分类时比较迷糊,参考了官方的题解可归结为找到index的节点进行插入。
class MyLinkedList {
int size;
ListNode head;
public MyLinkedList() {
size = 0;
head = new ListNode(0);
}
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;
}
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 > size) {
return;//不存在
}
index = Math.max(0, index);//保证index指向节点存在
size++;//统计结点数
ListNode pred = head;
for (int i = 0; i < index; i++) {
pred = pred.next;//遍历到index-1的节点,pred指向index
}
ListNode toAdd = new ListNode(val);
toAdd.next = pred.next;
pred.next = toAdd;
}
public void deleteAtIndex(int index) {
if (index < 0 || index >= size) {
return;
}
size--;
ListNode pred = head;
for (int i = 0; i < index; i++) {
pred = pred.next;
}
pred.next = pred.next.next;
}
}
反转链表 借助一个中间指针进行节点的保存
// 双指针
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;
}
}