203.链表移除元素
移除头结点和移除其他节点的操作是不一样的,因为链表的其他节点都是通过前一个节点来移除当前节点,而头结点没有前一个节点。
所以头结点如何移除呢,其实只要将头结点向后移动一位就可以,这样就从链表中移除了一个头结点。
class Solution {
public ListNode removeElements(ListNode head, int val) {
while (head != null && head.val == val) {
head = head.next;
}
ListNode curr = head;
while (curr != null) {
while (curr.next != null && curr.next.val == val) {
curr.next = curr.next.next;
}
curr = curr.next;
}
return head;
}
}
707.创建自己的链表
在初始设置值为0的虚拟头节点,然后在后续都在存在虚拟头节点的情况下操作,学习这个思想。
每一个单独的方法都要首先考虑index小于0和大于size(链表元素个数)的情况,然后再判断正常情况下的操作,这道题需要全面看待,addatHead和addatTail都是addIndex的特殊情况。
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);
size++;
ListNode pred = head;
for (int i = 0; i < index; i++) {
pred = pred.next;
}
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 ListNode {
int val;
ListNode next;
public ListNode(int val) {
this.val = val;
}
}
206.反转链表
这道题巩固链表逆置操作,要与数组逆置比较看
自己的啰嗦版:
设立p指针对应当前位置,q指针对应下一个位置,head指针对应上一个位置,按顺序改变指针,记得在开始判断空链表和仅有一个元素的链表的情况。循环结束条件是当前p指针为null。
class Solution {
public ListNode reverseList(ListNode head) {
if(head==null||head.next==null)
return head;
ListNode p = head.next;
ListNode q = p.next;
head.next = null;
while (p != null) {
p.next=head;
head=p;
p=q;
if(q!=null)
q=q.next;
}
return head;
}
}
leetcode简洁版:
每次先记录下一个节点,然后将当前节点指针指向pre,最后移动cur和pre。
class Solution {
public ListNode reverseList (ListNode head){
ListNode prev = null;
ListNode curr = head;
while (curr != null) {
ListNode next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
return prev;
}
}
终极简洁版(递归):
红色最深层递归,绿色次深处,黄色最后一层递归。
class Solution {
public ListNode reverseList(ListNode head) {
if (head == null || head.next == null)
return head;//找到链表尾部,新的头节点
ListNode newhead=reverseList(head.next);//递归深入,当找到尾部时,此时head是倒数第二个节点
head.next.next=head;//将当前的head和head.next指针翻转
head.next=null;//每一次都将head。next指向null,方便最后的原始头节点指向null
return newhead;//将找到的newhead每次都传承下去
}
}