leetcode上鍊表的題目還算不少的,暫時收錄下面這些,可能有些被我分到其他部分去了。
code:
class Solution {
public:
ListNode *addTwoNumbers(ListNode *l1, ListNode *l2) {
int carry=0;
ListNode* dummy = new ListNode(0),*ite=dummy;
while(l1&&l2){
int num = l1->val+l2->val+carry;
carry = num/10;
num %=10;
ite->next = new ListNode(num);
ite = ite->next;
l1 = l1->next;
l2 = l2->next;
}
l1 = l2?l2:l1;
while(l1){
int num = l1->val+carry;
carry = num/10;
num %=10;
ite->next = new ListNode(num);
ite=ite->next;
l1 = l1->next;
}
if(carry){
ite->next = new ListNode(carry);
ite = ite->next;
}
ite->next = NULL;
ite = dummy->next;
delete dummy;
return ite;
}
};
這個題比較簡單,寫起來陷阱也不算多,一個改版是,如果鏈表的數字是倒過來的,怎麼做?也就是說鏈表頭是最高位的數字而不是最低位。可以用遞歸做。
這個是很久之前寫的代碼,O(n)時間+O(n)空間。應該在代碼風格和效率上還有可以優化的地方,暫時放在這裏,以後有好的代碼再補一個。
code:
class Solution {
public:
ListNode *partition(ListNode *head, int x) {
ListNode* p1 = head;
if(head==NULL) return head;
vector<int> vec;
while(p1!=NULL){
vec.push_back(p1->val);
p1 = p1->next;
}
p1 = head;
bool sign = true;
int pos = 0;
while(p1!=NULL){
while(sign&&pos<vec.size()&&vec[pos]>=x)
pos++;
while(!sign&&pos<vec.size()&&vec[pos]<x)
pos++;
if(pos<vec.size()){
p1->val = vec[pos++];
p1 = p1->next;
}else{
if(!sign)
p1 = p1->next;
sign = false;
pos = 0;
}
}
return head;
}
};
關於這個題,還有一個很相似的版本,是要求O(n)時間+O(1)空間做到這個事情,不過給的不是鏈表,而是數組。我估摸着要是能做到,豈不是可以寫出一個穩定的快排??不知道怎麼搞。
Remove Duplicates from Sorted List
code:
class Solution {
public:
ListNode *deleteDuplicates(ListNode *head) {
ListNode *ite,*pre=head;
if(!head) return head;
ite = head->next;
while(ite){
if(ite->val==pre->val){
pre->next = ite->next;
delete ite;
}else
pre = ite;
ite = pre->next;
}
return head;
}
};
一開始沒注意是sorted,寫了個沒有sorted的代碼,順便也附上:
class Solution {
public:
ListNode *deleteDuplicates(ListNode *head) {
ListNode* dummy = new ListNode(1),*ite,*pre=dummy;;
dummy->next = head;
ite = head;
set<int> s;
while(ite){
if(s.find(ite->val)!=s.end()){
pre->next = ite->next;
delete ite;
ite=pre->next;
}else{
s.insert(ite->val);
pre = ite;
ite = ite->next;
}
}
head = dummy->next;
delete dummy;
return head;
}
};
Remove Duplicates from Sorted List II
code:
class Solution {
public:
ListNode *deleteDuplicates(ListNode *head) {
ListNode* dummy = new ListNode(1);
dummy->next = head;
bool sign = false;
ListNode* pre = dummy,*ite=head;
while(ite){
if(sign||(ite->next&&ite->next->val==ite->val)){
if(!ite->next||ite->next->val!=ite->val)
sign =false;
else sign = true;
pre->next = ite->next;
delete ite;
}else{
pre=ite;
}
ite = pre->next;
}
head = dummy->next;
delete dummy;
return head;
}
};
Remove Nth Node From End of List
code:
class Solution {
public:
ListNode *removeNthFromEnd(ListNode *head, int n) {
ListNode** ite = &head, *runner = head,*tmp;
while(n--&&runner)
runner = runner->next;
if(n+1) return head;
while(runner)
{
runner = runner->next;
ite = &((*ite)->next);
}
tmp = *ite;
(*ite) = (*ite)->next;
delete tmp;
return head;
}
};
這個代碼的思路就是讓一個指針先走n步,那第一個指針到了尾之後,第二個指針就是倒數第n個,然後刪掉。
另一個思路是遞歸,遞歸結束時記錄當前是倒數第幾個節點:
class Solution { public: int DelRecursive(ListNode* head,int n){ if(!head) return 0; int k = DelRecursive(head->next,n); if(n==k){ ListNode* tmp = head->next; head->next = head->next->next; delete tmp; } return k+1; } ListNode *removeNthFromEnd(ListNode *head, int n) { ListNode* dummy = new ListNode(0); dummy->next = head; DelRecursive(dummy,n); head = dummy->next; delete dummy; return head; } };
class Solution {
public:
ListNode *reverseBetween(ListNode *head, int m, int n) {
ListNode* dummy = new ListNode(1),*ite = dummy,*tail;
dummy->next = head;
for(int i=1;i<m;i++)
ite=ite->next;
head = ite;
tail = ite->next;
//先斷開,再連接,順序很重要,第m個不用管
for(int i=0;i<n-m;i++){
ite = tail->next;
tail->next = ite->next;
ite->next = head->next;
head->next = ite;
}
head = dummy->next;
delete dummy;
return head;
}
};
記住先斷開再連接。爲了體驗一下指針的指針跟dummy head的區別,這個題分別用兩種方法做了一遍:
2D Pointer code:
class Solution {
public:
ListNode *swapPairs(ListNode *head) {
ListNode** ite = &head;
while(*ite&&(*ite)->next)
{
ListNode* tmp = (*ite)->next;
(*ite)->next = tmp->next;
tmp->next = *ite;
*ite = tmp;
ite = &((*ite)->next->next);
}
return head;
}
};
dummy head code:
class Solution {
public:
ListNode *swapPairs(ListNode *head) {
ListNode* dummy = new ListNode(0),*ite=dummy;
dummy->next = head;
while(ite->next&&ite->next->next){
ListNode* tmp = ite->next->next;//保存要拿走的節點
ite->next->next = tmp->next; //刪除該節點
tmp->next = ite->next; //把該節點接到ite後面
ite->next = tmp;
ite = tmp->next;
}
ite = dummy->next;
delete dummy;
return ite;
}
};