也很精彩难分伯仲的一道题,简单的令人意外
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
if(l1 == nullptr) return l2;
if(l2 == nullptr) return l1;
if(l1->val <= l2->val){
l1->next = mergeTwoLists(l1->next,l2);
return l1;
}
l2->next = mergeTwoLists(l1,l2->next);
return l2;
}
};
迭代思路:新建一个链表头最简单,不以任何一个链表为基准:
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
ListNode* preHead = new ListNode(-1);
ListNode* prev = preHead;
while (l1 != nullptr && l2 != nullptr) {
if (l1->val < l2->val) {
prev->next = l1;
l1 = l1->next;
} else {
prev->next = l2;
l2 = l2->next;
}
prev = prev->next;
}
// 合并后 l1 和 l2 最多只有一个还未被合并完,我们直接将链表末尾指向未合并完的链表即可
prev->next = l1 == nullptr ? l2 : l1;
return preHead->next;
}
};
很精彩的一边过链表得倒数第k个节点的题,感觉要用到数学知识:19. 删除链表的倒数第 N 个结点
为什么还要截图下面两个示例,就是因为下面两个示例才是本题思路的第二个难点(第一个是怎么一遍过:双指针)
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode *p=head,*q=head;
for(int i=0;i<n;i++){
p=p->next;
}
if(p == nullptr && q->next == nullptr) return nullptr;
else if(p == nullptr && q->next != nullptr) return head->next;
while(p->next){
p = p->next;
q = q->next;
}
cout<<"here0"<<endl;
cout<<q->val<<endl;
q->next = q->next->next;
return head;
}
};
06.从尾到头打印链表
利用vector的从头插入功能:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
vector<int> reversePrint(ListNode* head) {
vector<int> c;
if(head == NULL){
return c;
}
while(head->next!=NULL){
c.insert(c.begin(),head->val);
head = head->next;
}
c.insert(c.begin(),head->val);
return c;
}
};
还可以push_back加reverse:
reverse反转法
while(head){
res.push_back(head->val);
head = head->next;
}
//使用algorithm算法中的reverse反转res
reverse(res.begin(),res.end());
return res;
18.删除指定节点
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* deleteNode(ListNode* head, int val) {
ListNode* p = head;
ListNode* q = p;
if(p->val == val){
head = head->next;
return head;
}
while(p->next){
q=p;
p=p->next;
if(p->val == val){
if(p->next) q->next = p->next;
else q->next = NULL;
break;
}
}
return head;
}
};
24.翻转链表
感想:重点在怎么去新建一个指针类型的节点并把指针指向这个新的节点。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(head == NULL || head->next == NULL) return head;
ListNode* tail = head;
stack<int> s;
while(tail->next){
s.push(tail->val);
tail = tail->next;
}
cout<<s.size()<<endl;
cout<<tail->val<<endl;
ListNode* p =tail;
while(!s.empty()){
ListNode* node = new ListNode(s.top());
s.pop();
p->next = node;
p = p->next;
}
return tail;
}
};
25.合并两个排序的链表
感想:最好的方法不是将L2插入l1,而是新建头结点,谁大往头结点后面续。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
if(l1 == NULL) return l2;
else if(l2 ==NULL) return l1;
ListNode* p;
if(l1->val<l2->val) {
p = l1;
l1 = l1->next;
}else{
p = l2;
l2 = l2->next;
}
ListNode* head = p;
while(l1 && l2){
cout<<"l1-l2 "<<l1->val<<" "<<l2->val<<endl;
if(l1->val < l2->val){
p->next = l1;
cout<<"l1 big"<<p->val<<endl;
p = p->next;
cout<<"l1 big"<<p->val<<endl;
l1 = l1->next;
cout<<"l1 big"<<p->val<<endl;
}else if(l1->val == l2->val){
p->next = l1;
p = p->next;
l1 = l1->next;
p->next = l2;
p = p->next;
l2 = l2->next;
cout<<p->val<<"="<<endl;
}else{
p->next = l2;
p = p->next;
l2 = l2->next;
cout<<"l2 big"<<p->val<<endl;
}
}
if(l1) p->next = l1;
if(l2) p->next = l2;
return head;
}
};