题目链接: 206.反转链表
解题思路:
建议食用题解中某大佬的思路展示,图文结合非常清晰here
代码:
//迭代版本,时间复杂度O(n),空间复杂度O(1)
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(head == NULL || head->next == NULL) return head;
ListNode *newhead = head;
while(head->next != NULL){
ListNode *p = head->next;
head->next = p->next;
p->next = newhead;
newhead = p;
}
return newhead;
}
};
//递归版本,时间复杂度O(n),空间复杂度O(n)
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(head == NULL || head->next == NULL) return head;
ListNode *newhead = reverseList(head->next);
head->next->next = head;
head->next = NULL;
return newhead;
}
};
题目链接: 203. 移除链表元素
解题思路:题目较简单,dummyhead的使用使得讨论的case大大减少。
代码:
//递归版本
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
if(head == NULL) return head;
ListNode *ret = removeElements(head->next, val);
if(head->val == val) return ret;
head->next = ret;
return head;
}
};
//迭代+虚拟头节点
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
if(head == NULL) return head;
ListNode *dummyhead = new ListNode(0);
dummyhead->next = head;
ListNode* r = dummyhead;
while(r->next != NULL){
if(r->next->val == val){
r->next = r->next->next;
}else{//此时若下一个节点需要删除,那么r应该保留位置,而不是前进
r = r->next;
}
}
return dummyhead->next;
}
};
题目链接: 328. 奇偶链表
解题思路:
代码:
class Solution {
public:
ListNode* oddEvenList(ListNode* head) {
if(head == NULL || head->next == NULL || head->next->next == NULL) return head;
ListNode *oddhead = head, *oddp = head;
ListNode *evenhead = head->next, *evenp = head->next;
while(oddp->next != NULL && evenp->next != NULL){
if(oddp->next != NULL && oddp->next->next != NULL){
oddp->next = oddp->next->next;
oddp = oddp->next;
}
else if(oddp->next == NULL || oddp->next->next == NULL) oddp->next = NULL;
if(evenp->next != NULL && evenp->next->next != NULL){
evenp->next = evenp->next->next;
evenp = evenp->next;
}
else if(evenp->next == NULL || evenp->next->next == NULL) evenp->next = NULL;
}
oddp->next = evenhead;
return oddhead;
}
};
//官方题解
class Solution {
public:
ListNode* oddEvenList(ListNode* head) {
if(head == NULL || head->next == NULL || head->next->next == NULL) return head;
ListNode *oddhead = head, *oddp = head;
ListNode *evenhead = head->next, *evenp = head->next;
while(evenp != NULL && evenp->next != NULL){
oddp->next = evenp->next;
oddp = oddp->next;
evenp->next = oddp->next;
evenp = evenp->next;
}
oddp->next = evenhead;
return oddhead;
}
};
题目链接: 234. 回文链表
解题思路:说几个比较推荐的解题思路
代码:
//快慢指针反转后半部分链表进行比较,
class Solution {
public:
bool isPalindrome(ListNode* head) {
if(head == NULL || head->next == NULL) return true;
ListNode *slow = head, *fast = head;
while(fast != NULL && fast->next != NULL && fast->next->next != NULL){
fast = fast->next->next;
slow =slow->next;
}
ListNode *cur = slow->next, *pre = NULL;
ListNode *save = cur->next;
while(save != NULL){
cur->next = pre;
pre = cur;
cur = save;
save = save->next;
}
cur->next = pre;
ListNode *p = cur;
ListNode *q = head;
while(p != NULL){
if(q->val != p->val) return false;
p = p->next;
q = q->next;
}
return true;
}
};
//快慢指针遍历翻转一遍过,
class Solution {
public:
bool isPalindrome(ListNode* head) {
if(head == NULL || head->next == NULL) return true;
if(head->next->next == NULL) return head->val == head->next->val;
ListNode *slow = head, *fast = head;
ListNode *pre = NULL, *save = head->next;
while(fast != NULL && fast->next != NULL && fast->next->next != NULL){
fast = fast->next->next;
slow->next = pre;
pre = slow;
slow = save;
save = save->next;
}
slow->next = pre;
if(fast->next == NULL) slow = slow->next;
while(save != NULL){
if(save->val != slow->val) return false;
save = save->next;
slow = slow->next;
}
return true;
}
};
题目链接: 21. 合并两个有序链表
解题思路:
经典迭代的想法,两个指针从两个链表各自出发分别比较,每次迭代中符合条件的插入到新链表后面,时间复杂度O(m+n),空间复杂度O(1)
代码:
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
ListNode *p1 = l1, *p2 = l2;
ListNode* resdummyhead = new ListNode(-1);
ListNode* restail = resdummyhead;
while(p1 != NULL && p2 != NULL){
if(p1->val < p2->val){
restail->next = p1;
restail = p1;
p1 = p1->next;
}
else{
restail->next = p2;
restail = p2;
p2 = p2->next;
}
}
if(p1 == NULL) restail->next = p2;
if(p2 == NULL) restail->next = p1;
return resdummyhead->next;
}
};
题目链接: 2. 两数相加
解题思路:
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode *p1 = l1;
ListNode *p2 = l2;
ListNode *resdummyhead = new ListNode(-1);
ListNode *resp = resdummyhead;
int count = 0;
while(p1 != nullptr || p2 != nullptr){
int addres;
if(p1 == nullptr) addres = p2->val + count;
else if(p2 == nullptr) addres = p1->val + count;
else addres = p1->val + p2->val + count;
count = 0;
if(addres >= 10){
count = 1;
addres = addres - 10;
}
ListNode *r = new ListNode(addres);
resp->next = r;
resp = r;
if(p1) p1 = p1->next;
if(p2) p2 = p2->next;
}
if(count == 1){
ListNode *r = new ListNode(1);
resp->next = r;
}
p1 = resdummyhead->next;
delete resdummyhead;
return p1;
}
};
题目链接: 430. 扁平化多级双向链表
解题思路:
//递归版本
class Solution {
public:
Node* flatten(Node* head) {
if(head == NULL) return NULL;
Node *p = head;
while(p != NULL){
if(p->child != NULL){
Node *temp = flatten(p->child);
Node *r = temp;
while(r->next != NULL) r = r->next;
p->child = NULL;
temp->prev = p;
r->next = p->next;
p->next = temp;
if(r->next != NULL)
r->next->prev = r;
p = r->next;
}
else p = p->next;
}
return head;
}
};
//迭代版本,推荐!
class Solution {
public:
Node* flatten(Node* head) {
Node *p = head;
while(p != NULL){
if(p->child != NULL){
Node *child = p->child;
Node *next = p->next;
p->child =NULL;
child->prev = p;
p->next = child;
while(child->next != NULL) child = child->next;
child->next = next;
if(next != NULL)
next->prev = child;
}
p = p->next;
}
return head;
}
};
题目链接: 138. 复制带随机指针的链表
解题思路:
class Solution {
public:
Node* copyRandomList(Node* head) {
if(head == NULL) return NULL;
Node *p = head;
while(p != NULL){
Node *node = new Node(p->val);
node->next = p->next;
p->next = node;
p = p->next->next;
}
p = head;
while(p != NULL){
if(p->random != NULL) p->next->random = p->random->next;
p = p->next->next;
}
p = head;
Node *newhead = head->next;
Node *np = newhead;
while(p != NULL){
p->next = np->next;
p = p->next;
if(p != NULL){
np->next = p->next;
np = np->next;
}
}
return newhead;
}
};
题目链接: 61. 旋转链表
解题思路:
代码:
class Solution {
public:
ListNode* rotateRight(ListNode* head, int k) {
if(head == nullptr || head->next == nullptr) return head;
int length = 1;
ListNode *p = head;
while(p->next != nullptr){
p = p->next;
length++;
}
p->next = head;
k = k % length;
p = head;
for(int i = 0; i < length-k-1; ++i){
p = p->next;
}
head = p->next;
p->next = nullptr;
return head;
}
};