第四天
链表篇
/**
* 给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。
*
*
* 示例 1:
* 输入:head = [1,2,6,3,4,5,6], val = 6
* 输出:[1,2,3,4,5]
* 示例 2:
*
* 输入:head = [], val = 1
* 输出:[]
* 示例 3:
*
* 输入:head = [7,7,7,7], val = 7
* 输出:[]
*
*
* 提示:
*
* 列表中的节点数目在范围 [0, 104] 内
* 1 <= Node.val <= 50
* 0 <= val <= 50
*/
public static class ListNode {
int val;
ListNode next;
ListNode() {}
ListNode(int val) { this.val = val; }
ListNode(int val, ListNode next) { this.val = val; this.next = next; }
}
/**
* 时间复杂度 O(n)
* 空间复杂度 O(1)
* @param head
* @param val
* @return
*/
public static ListNode removeElements(ListNode head, int val) {
ListNode listNode = head;
while (listNode.next.next!=null){
while (listNode.next!=null&&listNode.next.val==val){
listNode.next = listNode.next.next;
}
listNode = listNode.next;
if(listNode==null||listNode.next==null){
break;
}
}
return head.next;
}
public static ListNode removeElements3(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;
}
/**
* 添加虚节点方式:添加一个指向当前循环链表节点的父节点
* 时间复杂度 O(n)
* 空间复杂度 O(1)
* @param head
* @param val
* @return
*/
public static ListNode removeElements2(ListNode head, int val) {
if (head == null) {
return head;
}
// 因为删除可能涉及到头节点,所以设置dummy节点,统一操作
ListNode dummy = new ListNode(-1, head);
ListNode pre = dummy;
ListNode cur = head;
while (cur != null) {
if (cur.val == val) {
pre.next = cur.next;
} else {
pre = cur;
}
cur = cur.next;
}
return dummy.next;
}
/**
* 你可以选择使用单链表或者双链表,设计并实现自己的链表。
*
* 单链表中的节点应该具备两个属性:val 和 next 。val 是当前节点的值,next 是指向下一个节点的指针/引用。
*
* 如果是双向链表,则还需要属性 prev 以指示链表中的上一个节点。假设链表中的所有节点下标从 0 开始。
*
* 实现 MyLinkedList 类:
*
* MyLinkedList() 初始化 MyLinkedList 对象。
* int get(int index) 获取链表中下标为 index 的节点的值。如果下标无效,则返回 -1 。
* void addAtHead(int val) 将一个值为 val 的节点插入到链表中第一个元素之前。在插入完成后,新节点会成为链表的第一个节点。
* void addAtTail(int val) 将一个值为 val 的节点追加到链表中作为链表的最后一个元素。
* void addAtIndex(int index, int val) 将一个值为 val 的节点插入到链表中下标为 index 的节点之前。如果 index 等于链表的长度,那么该节点会被追加到链表的末尾。如果 index 比长度更大,该节点将 不会插入 到链表中。
* void deleteAtIndex(int index) 如果下标有效,则删除链表中下标为 index 的节点。
*
*
* 示例:
*
* 输入
* [“MyLinkedList”, “addAtHead”, “addAtTail”, “addAtIndex”, “get”, “deleteAtIndex”, “get”]
* [[], [1], [3], [1, 2], [1], [1], [1]]
* 输出
* [null, null, null, null, 2, null, 3]
*
* 解释
* MyLinkedList myLinkedList = new MyLinkedList();
* myLinkedList.addAtHead(1);
* myLinkedList.addAtTail(3);
* myLinkedList.addAtIndex(1, 2); // 链表变为 1->2->3
* myLinkedList.get(1); // 返回 2
* myLinkedList.deleteAtIndex(1); // 现在,链表变为 1->3
* myLinkedList.get(1); // 返回 3
*
*
* 提示:
*
* 0 <= index, val <= 1000
* 请不要使用内置的 LinkedList 库。
* 调用 get、addAtHead、addAtTail、addAtIndex 和 deleteAtIndex 的次数不超过 2000 。
*
* 来源:力扣(LeetCode)
* 链接:力扣原题链接
*/
static class ListNode2 {
int val;
ListNode2 next;
ListNode2(){}
ListNode2(int val) {
this.val=val;
}
}
static class MyLinkedList {
private final ListNode2 first;
private ListNode2 last;
public int size;
public MyLinkedList() {
size = 0;
first = new ListNode2(0);
last = first;
}
public int get(int index) {
if(size<=index||index<0){
return -1;
} else {
ListNode2 listNode = this.first;
while (index>=0){
if(index==0){
return listNode.val;
} else {
listNode = listNode.next;
index--;
}
}
}
return -1;
}
public void addAtHead(int val) {
ListNode2 newHeadNode = new ListNode2(val);
newHeadNode.next = this.first.next;
this.first.next = newHeadNode;
if(newHeadNode.next == null){
this.last = newHeadNode;
}
this.size++;
}
public void addAtTail(int val) {
ListNode2 newTailNode = new ListNode2(val);
this.last.next = newTailNode;
this.last = newTailNode;
size++;
}
public void addAtIndex(int index, int val) {
if (index <= 0 || index >= size) {
if (index == size) {
addAtTail(val);
} else if (index == 0) {
addAtHead(val);
}
return;
}
int i = 0;
for (ListNode2 x = first; x.next != null; x = x.next, ++i) {
if (i == index) {
ListNode2 node = new ListNode2(val);
node.next = x.next;
x.next = node;
size++;
}
}
}
public void deleteAtIndex(int index) {
if (index < 0 || index >= size) {
return;
}
int i = 0;
for (ListNode2 x = first; x.next != null; x = x.next, ++i) {
if (i == index) {
x.next = null == x.next.next ? null : x.next.next;
size--;
if (size == 0) {
last = first;
} else if (index == size) {
last = x;
}
return;
}
}
}
}
欢迎各位大佬在评论区指点讨论
参考链接:代码随想路