链表篇(上 代码随想录二刷+总结)
1.移除链表元素
leetcode 203
class Solution {
public ListNode removeElements(ListNode head, int val) {
ListNode newHead = new ListNode(0,head);
ListNode pre = newHead;
while(head!=null){
if(head.val==val){
pre.next = head.next;
head = head.next;
}else{
pre = head;
head = head.next;
}
}
return newHead.next;
}
}
链表问题一般要考虑构建虚拟节点,让整个链表可以具有统一的操作。这道题就是最基本操作,只做太久没做链表题的复习。
2.设计链表
leetcode 707
class MyLinkedList {
class Node{
int val;
Node next;
Node(int val){
this.val = val;
}
}
int length;
Node head;
public MyLinkedList() {
//初始化
head = null;
length=0;
}
public int get(int index) {
if(index>=length||index<0){
return -1;
}
int i=0;
Node getNode = head;
while(i<index){
getNode = getNode.next;
i++;
}
return getNode.val;
}
public void addAtHead(int val) {
Node newHead = new Node(val);
newHead.next = head;
head = newHead;
length++;
}
public void addAtTail(int val) {
Node MyNode = new Node(val);
MyNode.next = null;
if(length == 0){
head = MyNode;
}else{
Node pre = head;
while(pre.next!=null){
pre = pre.next;
}
pre.next = MyNode;
}
length++;
}
public void addAtIndex(int index, int val) {
if(index>length){
return;
}
if(index<=0){
addAtHead(val);
return;
}
if(index == length){
addAtTail(val);
return;
}
Node temp = head;
int i = 0;
while(i<index-1){
temp = temp.next;
i++;
}
Node addNode = new Node(val);
addNode.next = temp.next;
temp.next = addNode;
length++;
}
public void deleteAtIndex(int index) {
if(index==0){
head = head.next;
length--;
}else if(index>0&&index<length){
Node temp = head;
for(int i=0;i<index-1;i++){
temp = temp.next;
}
temp.next = temp.next.next;
length--;
}
}
}
练手复习即可
3.反转链表
leetcode 206
class Solution {
public ListNode reverseList(ListNode head) {
ListNode pre = null;
ListNode NEXT;
ListNode cur = head;
while(cur!=null){
NEXT = cur.next;
cur.next = pre;
pre = cur;
cur = NEXT;
}
return pre;
}
}
因为一个节点反转后无法找到正序的下一个节点,所以反转过程前记录下一个节点。
4.两两交换链表中的节点
leetcode 24
class Solution {
public ListNode swapPairs(ListNode head) {
ListNode cur = new ListNode(-1,head);
ListNode res = cur;
while(cur.next!=null&&cur.next.next!=null){
ListNode temp1 = cur.next.next.next;
ListNode temp2 = cur.next;
cur.next = cur.next.next;
cur.next.next = temp2;
cur.next.next.next = temp1;
cur = cur.next.next;
}
return res.next;
}
}
注意:循环中cur.next = cur.next.next这类的操作,就表示链表的结构已经发生改变,要从新的链表结构去找相应结点,而不是旧的结构,用下面这个代码,事先就缓存了旧结构的位置,就不用考虑当次循环下,新结构中相对位置,建议使用下面这种更易理解,上面一种容易绕晕。(画图理解)
class Solution {
public ListNode swapPairs(ListNode head) {
ListNode virtueNode = new ListNode(0,head);
ListNode tem = virtueNode;
while(tem.next!=null&&tem.next.next!=null){
ListNode node1 = tem.next;
ListNode node2 = tem.next.next;
tem.next = node2;
node1.next = node2.next;
node2.next = node1;
tem = node1;
}
return virtueNode.next;
}
}