目录
leetcode:203.移除链表元素
题目链接:https://leetcode.cn/problems/remove-linked-list-elements/
方法一 添加哨兵节点
1 方法思想
使用哨兵结点指向链表的第一个结点,处理时对链表结点进行同一对待即可,不需要单独判断链表的第一个结点。
2 代码实现
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode removeElements(ListNode head, int val) {
ListNode sentry = new ListNode(0, head);
ListNode pre = sentry;
ListNode cur = head;
while (cur != null) {
if (cur.val == val) {
pre.next = cur.next;
cur.next = null;
} else {
pre = pre.next;
}
cur = pre.next;
}
return sentry.next;
}
}
3 复杂度分析
时间复杂度:O(n)
空间复杂度:O(1)
4 涉及到知识点
链表,哨兵节点
方法二 不设哨兵节点
1 方法思想
2 代码实现
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode removeElements(ListNode head, int val) {
while (head != null && head.val == val) {
head = head.next;
}
if(head == null) return head;
ListNode pre = head;
ListNode cur = head.next;
//ListNode temp = new ListNode()
while (cur != null) {
if (cur.val == val){
pre.next = cur.next;
cur.next = null;
}else {
pre = pre.next;
}
cur = pre.next;
}
return head;
}
}
3 复杂度分析
时间复杂度:O(n)
空间复杂度:O(1)
4 涉及到知识点
链表,哨兵节点
收获
不管题目简单与否还是要手动实现一下,避免有小坑。
学习链接
https://programmercarl.com/0704.%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE.html#%E6%80%9D%E8%B7%AF
707. Design Linked List
题目链接:https://leetcode.cn/problems/design-linked-list/
方法一 单链表
1 方法思想
只有next指针,设置哨兵节点
2 代码实现
public class MyLinkedList {
class ListNode {
int val;
ListNode next;
ListNode() {}
ListNode(int val) { this.val = val; }
ListNode(int val, ListNode next) { this.val = val; this.next = next; }
}
int size;
ListNode head;
ListNode sentry;
public MyLinkedList() {
sentry = new ListNode(0);
size = 0;
}
public MyLinkedList(ListNode head) {
sentry.next = head;
size++;
}
public int get(int index) {
if (index >= size){
return -1;
}
ListNode cur = sentry.next;
while (index > 0){
cur = cur.next;
index --;
}
return cur.val;
}
public void addAtHead(int val) {
//ListNode insert = new ListNode(val);
addAtIndex(0, val);
}
public void addAtTail(int val) {
addAtIndex(size, val);
}
public void addAtIndex(int index, int val) {
if (index > size) return;
ListNode insert = new ListNode(val);
ListNode cur = sentry;
while (index > 0){
index --;
cur = cur.next;
}
insert.next = cur.next;
cur.next = insert;
size ++;
}
public void deleteAtIndex(int index) {
if (index >= size) return;
ListNode delete = sentry;
while (index > 0){
index --;
delete = delete.next;
}
delete.next = delete.next.next;
size --;
}
}
方法二 双链表
1 方法思想
有next和pre指针,增添哨兵指针
2 代码实现
class MyLinkedList {
class listNode {
int val;
listNode next = null;
listNode prev = null;
public listNode() {
}
public listNode(int val) {
this.val = val;
}
}
int size;
listNode head;
listNode tail;
public MyLinkedList() {
size = 0;
head = new listNode(0);
tail = new listNode(0);
head.next = tail;
tail.prev = head;
}
public int get(int index) {
if (index < 0 || index >= size) return -1;
listNode cur = null;
if (index < size / 2) {
cur = head;
for (int i = index; i >= 0; i--) {
cur = cur.next;
}
} else {
cur = tail;
for (int i = size - index - 1; i >= 0; i--) {
cur = cur.prev;
}
}
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 < 0 || index > size) return;
listNode node = new listNode(val);
if (index <= size / 2) {
// 从头开始插入
listNode pre = head;
for (int i = index; i > 0; i--) {
pre = pre.next;
}
node.next = pre.next;
pre.next.prev = node;
pre.next = node;
node.prev = pre;
} else {
// 从尾部开始插入
listNode tai = tail;
int step = size - index;
for (int i = step; i > 0; i--) {
tai = tai.prev;
}
tai.prev.next = node;
node.prev = tai.prev;
node.next = tai;
tai.prev = node;
}
size++;
}
public void deleteAtIndex(int index) {
if (index < 0 || index >= size) return;
if (index <= size / 2) {
listNode pre = head;
for (int i = index; i > 0; i--) {
pre = pre.next;
}
listNode node = pre.next;
node.next.prev = pre;
pre.next = node.next;
node.next = null;
node.prev = null;
} else {
listNode tai = tail;
int step = size - index - 1;
for (int i = step; i > 0; i--) {
tai = tai.prev;
}
listNode node = tai.prev;
node.prev.next = tai;
tai.prev = node.prev;
node.prev = null;
node.next = null;
}
size--;
}
}
3 复杂度分析
时间复杂度:
空间复杂度:
学习链接
https://programmercarl.com/0707.%E8%AE%BE%E8%AE%A1%E9%93%BE%E8%A1%A8.html#%E5%85%B6%E4%BB%96%E8%AF%AD%E8%A8%80%E7%89%88%E6%9C%AC
206. Reverse Linked List
题目链接:https://leetcode.cn/problems/reverse-linked-list/
方法一 设置哨兵节点
1 方法思想
遍历节点依次插入哨兵节点的后面
2 代码实现
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
if (head == null || head.next == null) return head;
ListNode sentry = new ListNode(0, head);
ListNode cur = head.next;
while (cur != null) {
head.next = cur.next;
cur.next = sentry.next;
sentry.next = cur;
cur = head.next;
}
return sentry.next;
}
}
3 复杂度分析
时间复杂度:O(n)
空间复杂度:O(1)