leetcode no.2 两数相加
- 两个逆序链表加和,只需要按位加,保留进位符,最后到两个空进位空结束
- 记得每次结束以后让当前链表位指向下一位,处理的和被处理的都是
- 要将结果头返回,所以要有一个专门的指针用来移位的
- 前面判断条件是两个链表都非空&&
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) { ListNode*ans=new ListNode(0); ListNode*realans=ans; int temp=0; while(l1!=NULL && l2!=NULL){ ans->next=new ListNode((l1->val+l2->val+temp)%10); temp=(l1->val+l2->val+temp)/10; ans=ans->next; l1=l1->next; l2=l2->next; } while(l1!=NULL) { ans->next=new ListNode((l1->val+temp)%10); temp=(l1->val+temp)/10; l1=l1->next; ans=ans->next; } while(l2!=NULL) { ans->next=new ListNode((l2->val+temp)%10); temp=(l2->val+temp)/10; l2=l2->next; ans=ans->next; } if(temp!=0) ans->next=new ListNode(temp); return realans->next; } };
leetcode no.19 删除链表的倒数第N个节点
- 双指针,让两个的距离为n-1
- 注意考虑删除的是第一个元素的情况
- pre指针用来删除的时候用,因此只要指针移动的时候存在就好了
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode* removeNthFromEnd(ListNode* head, int n) { ListNode*temp1=head; ListNode*temp2=head; ListNode*pre; for(int i=1;i<n;i++) temp2=temp2->next; if(temp2->next==NULL) return head->next; while(temp2->next!=NULL) { pre=temp1; temp1=temp1->next; temp2=temp2->next; } pre->next=temp1->next; return head; } };
leetcode no.21 合并两个有序链表
- 两个不为空就比,为空就连上
- 可以不新生成节点直接连原来的会更节省内存(因为不用新生成节点),面试学到的,看leetcode标程也是这么说的。。但那个结果显示就很奇怪。。不管了
- 只有原地调整链表才是o1空间哦,多一个指针,不然反复新生成是要占用的
- 两条原始链表并不需要保存头,因此可以直接移动指针,不用新加
/** * 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* mergeTwoLists(ListNode* l1, ListNode* l2) { ListNode*temp1=l1; ListNode*temp2=l2; ListNode*ans=new ListNode(0); ListNode*realans=ans; while(temp1!=NULL && temp2!=NULL) { if(temp1->val<=temp2->val) { ans->next=temp1; temp1=temp1->next; ans=ans->next; } else { ans->next=temp2; temp2=temp2->next; ans=ans->next; } } if(temp1!=NULL) ans->next=temp1; if(temp2!=NULL) ans->next=temp2; return realans->next; } };
leetcode no.23 合并k个升序链表
- 类似归并的思路(这个两个两个来再变多的思路叫分治法)
- 本质上是两个两个合并,然后合成长的在两个合并,降低复杂度到log
- 调用合并两个升序链表的代码
- 每次步长是step*2,以二倍的速度增长
- j每次从0开始,然后下一个j是跨越两倍步长的值,两倍哦!因为step代表的是,同组即将合并的两个之间的距离,那么第二个和下一组第一个也是这个距离,所以是两个,千万不要搞错然后反复合并浪费时间
- 注意空vector,特判len==0 直接返回NULL
- 每次保留在较小的下标对应链表中,节省空间哦
/** * 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*mergetwo(ListNode*l1,ListNode*l2) { ListNode*temp1=l1; ListNode*temp2=l2; ListNode*ans=new ListNode(0); ListNode*realans=ans; while(l1 && l2) { if(l1->val<=l2->val) { ans->next=l1; l1=l1->next; ans=ans->next; } else { ans->next=l2; l2=l2->next; ans=ans->next; } } if(l1) ans->next=l1; if(l2) ans->next=l2; return realans->next; } ListNode* mergeKLists(vector<ListNode*>& lists) { int len=lists.size(); if(len==0) return NULL; for(int step=1;step<=len;step=step*2) { for(int j=0;j<=len-1;j=j+step*2) { if(j+step<=len-1) lists[j]=mergetwo(lists[j],lists[j+step]); } } return lists[0]; } };
leetcode no.24 两两交换链表中的节点
- 前面加一个空节点,从空节点开始pre,之后两个一组如果都不为空就倒置
- 两个点交换,就是哪个前面连着的新的更新好了,接下来就修改那个,注意最后是pre->next->next,不要手误
- 返回的结果是空节点的下一个,不要直接返回head,那样会把修改后新的head节点漏掉
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: void change(ListNode*pre) { ListNode*temp=pre->next; pre->next=temp->next; temp->next=pre->next->next; pre->next->next=temp; } ListNode* swapPairs(ListNode* head) { ListNode*newHead=new ListNode(0); newHead->next=head; ListNode*pre=newHead; while(pre->next!=NULL && pre->next->next!=NULL) { change(pre); pre=pre->next->next; } return newHead->next; } };
时间才能证明一切,选好了就尽力去做吧!