DAY3 链表、LeetCode203、707、206
1.链表
每个节点有两部分,存储数据的data和指向下一个节点的next指针。链表在内存中不是连续的。
public class ListNode{
int val;
ListNode next;
//节点的构造函数(无参)
public void ListNode(){
}
//节点的构造函数(一个参数)
public void ListNode(int val){
this.val = val;
}
//节点的构造函数(两个参数)
public void ListNode(int val, ListNode next){
this.val = val;
this.next = next;
}
}
2.LeetCode203:移除链表节点
给你一个链表的头节点 head
和一个整数 val
,请你删除链表中所有满足 Node.val == val
的节点,并返回 新的头节点 。
题解:设置虚拟头节点,依次遍历删除符合的节点。
ListNode dummy = new ListNode(-100, head);//设置虚拟头节点,值为-100,下一个节点为head
ListNode cur = dummy;
while(cur.next != null){
if(cur.next.val == val){
cur.next = cur.next.next;
}else //必须加else。若不加则遇到连续的两个val时会漏掉第二个
cur = cur.next;
}
return dummy.next;
3.LeetCode707:设计链表
class ListNode{ //用来定义节点的类
int val;
ListNode next;
public ListNode(){};
public ListNode(int val){ this.val = val;}
public ListNode(int val, ListNode next){ this.val = val; this.next = next;}
}
class MyLinkedList { //用来定义链表的类
int size; //定义链表元素个数
ListNode dummy; //定义链表虚拟头节点
public MyLinkedList() { //链表的构造函数
size = 0; //初始化size为0
dummy = new ListNode(-1); //添加虚拟头节点,值为-1,下标为0
}
//获取下标为index的元素
public int get(int index) {
if(index < 0 || index >= size){
return -1;
}
ListNode cur = dummy;
for(int i = 0; i <= index; i++){//添加了虚拟头节点,所以查找 index+1
cur = cur.next;
}
return cur.val;
}
//添加值为 val 的节点到链表中的第一个元素之前
public void addAtHead(int val) {
ListNode temp = new ListNode(val);//定义新节点时默认其后为null
temp.next = dummy.next;
dummy.next = temp;
size++;
//addAtIndex(0,val);
}
//添加值为 val 的节点到链表的最后
public void addAtTail(int val) {
ListNode temp = new ListNode(val); //定义新节点时默认其后为null
ListNode tail = dummy;
while(tail.next != null){
tail = tail.next;
}
tail.next = temp;
size++;
//addAtIndex(size,val);
}
//添加值为 val 的节点到下标为 index 的节点之前
public void addAtIndex(int index, int val) {
ListNode temp = new ListNode(val);
ListNode prev = dummy;
if(index > size) return;
for(int i = 0; i < index; i++){
prev = prev.next;
}
temp.next = prev.next;
prev.next = temp;
size++;
}
//如果下标有效,则删除链表中下标为 index 的节点
public void deleteAtIndex(int index) {
if(index < 0 || index >= size)
return;
if(index == 0){
dummy = dummy.next;
return;
}
ListNode prev = dummy;
for(int i = 0; i < index; i++){
prev = prev.next;
}
prev.next = prev.next.next;
size--;
}
}
4.LeetCode206:反转链表
你单链表的头节点 head
,请你反转链表,并返回反转后的链表。
题解:
head为当前节点,用cur保存head的下一个节点,用prev保存head的上一个节点。head指向prev,然后 prev 和 head 均向后移动。
ListNode prev = null;
ListNode cur = head;
while(head != null){
cur = head.next;
head.next = prev;
prev = head;
head = cur;
}
return prev;