链表
3. 设计链表
思路:
没啥思路,照着实现就行,熟悉 C++ 类的语法,注意一些判据细节即可。
class MyLinkedList {
public:
// 定义链表结构体
struct LinkedNode {
int val;
LinkedNode *next;
LinkedNode(int val):val(val), next(nullptr){}
};
MyLinkedList() {
_dummyHead = new LinkedNode(0);
_size = 0;
}
int get(int index) {
if (index >= _size || index < 0) return -1;
LinkedNode *cur = _dummyHead->next;
while (index--) {
cur = cur->next;
}
return cur->val;
}
void addAtHead(int val) {
LinkedNode *tmp = new LinkedNode(val);
tmp->next = _dummyHead->next;
_dummyHead->next = tmp;
_size++;
}
void addAtTail(int val) {
LinkedNode *tmp = new LinkedNode(val);
LinkedNode *cur = _dummyHead;
while (cur->next) cur = cur->next;
cur->next = tmp;
_size++;
}
void addAtIndex(int index, int val) {
if (index < 0) addAtHead(val);
else if (index > _size) return ;
else {
LinkedNode *tmp = new LinkedNode(val);
LinkedNode *cur = _dummyHead;
while (index--) {
cur = cur->next;
}
tmp->next = cur->next;
cur->next = tmp;
_size++;
}
}
void deleteAtIndex(int index) {
if (index < 0 || index >= _size) return ;
LinkedNode *cur = _dummyHead;
while (index--) {
cur = cur->next;
}
LinkedNode *tmp = cur->next;
cur->next = cur->next->next;
delete tmp;
_size--;
}
private:
LinkedNode *_dummyHead;
int _size;
};
/**
* 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);
*/
4. 反转链表
思路:
每次以三个点为一组:cur1 为第一个点,head 为第二个点,cur2 为第三个点;
首先将 head 后一个点地址记录下来(下面用 cur2 来记录);
然后将 head 指向 cur1,此时 head 与 cur2 的指向断开了,就需要利用 cur2 向后寻找了;
然后将 cur1 移动到之前的 head 处,head 移动到 cur2 ,即第三个点处,此时,cur1 与 head 、cur2 构成一组新的点;
重复上面步骤至 cur2 所在节点为空,此时 head 的位置就是新链表的头节点。
借用卡哥的动图,更方便理解:
下图中,pre 为 cur1,cur 为 head,cur2没有标出,用来记录下一个链节的位置。
class Solution {
public:
ListNode* reverseList(ListNode* head) {
// 首先处理链表长度小于 2 的情况
if (head == nullptr) return nullptr;
if (head->next == nullptr) return head;
// 构建 3 个连续的点对
ListNode *cur1 = head;
head = cur1->next;
ListNode *cur2 = head->next;
// 首先处理头部,因为初始的头节点要置为 nullptr
head->next = cur1;
cur1->next = nullptr;
cur1 = head;
while (cur2) {
head = cur2;
cur2 = head->next;
head->next = cur1;
cur1 = head;
}
return head;
}
};