0.引言
1.移除鏈表元素
Category | Difficulty | Likes | Dislikes |
---|---|---|---|
algorithms | Easy (54.74%) | 1174 | - |
給你一個鏈表的頭節點 head
和一個整數 val
,請你刪除鏈表中所有滿足 Node.val == val
的節點,并返回 新的頭節點 。
示例 1:
image.png
輸入: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, 10<sup>4</sup>]
內 1 <= Node.val <= 50
0 <= val <= 50
1.1.自己想法及代碼實現
emmmm 看題目的時候已經看到提示了,需要用虛擬節點,虛擬節點的使用可以避免刪除節點為頭結點的case:
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
if (head == nullptr) return nullptr;
ListNode* fake_head = new ListNode(0);
fake_head->next = head;
ListNode* cur = fake_head;
while (cur->next) {
if (cur->next->val == val) {
cur->next = cur->next->next;
} else {
cur = cur->next;
}
}
return fake_head->next;
}
};
1.2.參考思想及代碼實現
image.png
要注意管理內存!!
// @lc code=start
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
if (head == nullptr) return nullptr;
ListNode* fake_head = new ListNode(0);
fake_head->next = head;
ListNode* cur = fake_head;
while (cur->next) {
if (cur->next->val == val) {
ListNode* tmp = cur->next;
cur->next = cur->next->next;
delete tmp; // 注意內存管理
} else {
cur = cur->next;
}
}
head = fake_head->next;
delete fake_head;
return head;
}
};
2.設計鏈表
Category | Difficulty | Likes | Dislikes |
---|---|---|---|
algorithms | Medium (34.75%) | 757 | - |
設計鏈表的實現。您可以選擇使用單鏈表或雙鏈表。單鏈表中的節點應該具有兩個屬性:val
和 next
。val
是當前節點的值,next
是指向下一個節點的指針/引用。如果要使用雙向鏈表,則還需要一個屬性 prev
以指示鏈表中的上一個節點。假設鏈表中的所有節點都是 0-index 的。
在鏈表類中實現這些功能:
- get(index):獲取鏈表中第
index
個節點的值。如果索引無效,則返回-1
。 - addAtHead(val):在鏈表的第一個元素之前添加一個值為
val
的節點。插入后,新節點將成為鏈表的第一個節點。 - addAtTail(val):將值為
val
的節點追加到鏈表的最后一個元素。 - addAtIndex(index,val):在鏈表中的第
index
個節點之前添加值為val
的節點。如果index
等于鏈表的長度,則該節點將附加到鏈表的末尾。如果index
大于鏈表長度,則不會插入節點。如果index
小于0,則在頭部插入節點。 - deleteAtIndex(index):如果索引
index
有效,則刪除鏈表中的第index
個節點。
示例:
MyLinkedList linkedList = new MyLinkedList();
linkedList.addAtHead(1);
linkedList.addAtTail(3);
linkedList.addAtIndex(1,2); //鏈表變為1-> 2-> 3
linkedList.get(1); //返回2
linkedList.deleteAtIndex(1); //現在鏈表是1-> 3
linkedList.get(1); //返回3
提示:
0 <= index, val <= 1000
- 請不要使用內置的 LinkedList 庫。
-
get
,addAtHead
,addAtTail
,addAtIndex
和deleteAtIndex
的操作次數不超過2000
。
2.1.自己想法及代碼實現
2.2.參考思想及代碼實現
基本是把答案看了一遍再來寫:
/*
* @lc app=leetcode.cn id=707 lang=cpp
*
* [707] 設計鏈表
*/
// @lc code=start
class MyLinkedList {
public:
MyLinkedList() : size_(0), fake_head_(new Node(0)) {}
int get(int index) {
if (index < 0 || index >= size_) return -1;
Node* cur = fake_head_->next;
while (index--) {
cur = cur->next;
}
return cur->val;
}
void addAtHead(int val) {
Node* add = new Node(val);
add->next = fake_head_->next;
fake_head_->next = add;
size_++;
}
void addAtTail(int val) {
Node* add = new Node(val);
Node* cur = fake_head_;
while (cur->next) {
cur = cur->next;
}
cur->next = add;
size_++;
}
void addAtIndex(int index, int val) {
// if (index < 0 || index > size_) return;
if (index < 0) index = 0;
if (index > size_) return;
Node* add = new Node(val);
Node* cur = fake_head_; // 這里直接等于fake_head_則是相當于插在之后
while (index--) {
cur = cur->next;
}
add->next = cur->next;
cur->next = add;
size_++;
}
void deleteAtIndex(int index) {
if (index < 0 || index >= size_) return;
Node* cur = fake_head_; // 這里等于fake_head_則相當于刪除后一個元素
while (index--) {
cur = cur->next;
}
Node* tmp = cur->next;
cur->next = cur->next->next;
delete tmp;
size_--;
}
public:
struct Node {
int val;
Node* next;
Node(int val) : val(val), next(nullptr) {}
};
private:
int size_;
Node* fake_head_;
};
/**
* Your MyLinkedList object will be instantiated and called as such:
* MyLinkedList* obj = new MyLinkedList();
* int param_1 = obj->get(index);
* obj->addAtHead(val);
* obj->addAtTail(val);
* obj->addAtIndex(index,val);
* obj->deleteAtIndex(index);
*/
// @lc code=end
3.反轉鏈表
Category | Difficulty | Likes | Dislikes |
---|---|---|---|
algorithms | Easy (73.49%) | 2992 | - |
給你單鏈表的頭節點 head
,請你反轉鏈表,并返回反轉后的鏈表。
示例 1:
image.png
輸入:head = [1,2,3,4,5]
輸出:[5,4,3,2,1]
示例 2:
image.png
輸入:head = [1,2]
輸出:[2,1]
示例 3:
輸入:head = []
輸出:[]
提示:
- 鏈表中節點的數目范圍是
[0, 5000]
-5000 <= Node.val <= 5000
進階:鏈表可以選用迭代或遞歸方式完成反轉。你能否用兩種方法解決這道題?
3.1.自己想法及代碼實現
頭插法吧:
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if (head == nullptr) return nullptr;
ListNode tmp = ListNode();
ListNode* cur = head;
while (cur) {
ListNode* cur_next = cur->next;
cur->next = tmp.next;
tmp.next = cur;
cur = cur_next;
}
return tmp.next;
}
};
4.總結
鏈表就得多做幾個題練習一下。
為什么發布是空的??
image.png
為什么發布不出去???