這篇用來放作的leetcode題目node
總結:ios
UPD 2018.3git
本身還須要注意的地方面試
1. 首先面試官說完題目以後,不要就急着 去想 趕忙把題目想出來,算法
首先該用本身的話向 面試官 複述一遍題意,確保沒有理解錯題意,在複述的過程當中,數組
能夠詢問 N (若是給了的話 )的範圍,還有題目中給出的別的數的範圍,確保後面寫代碼的過程用int 仍是long longdom
假定輸入都合法嗎 ? (確保後面寫代碼的時候 要不要寫上對特殊狀況的處理ide
輸入會超限制嗎?優化
... 暫時想到這些ui
2. 沒有思路的話,能夠一步一步的說本身的想法,同時在這個過程 能夠接着想 更好的作法
不要什麼都不說,
3. 編一些簡單的樣例 幫助想題目 和 寫代碼
4.想一些優化,時間,空間都想想,還能不能再優化
5.寫完代碼以後,檢查本身的代碼有沒有一些小細節的錯誤,爭取bugfree
UPD 2018.5.25
1.對輸入數據 存在的狀況 必定要問清楚 若是是讓合併鏈表的話,問清楚 鏈表是否還有環,或者兩個輸入鏈表是否已經相交 ?
UPD 2018.6.5
1. 假如給了一個字典,記得考慮字典內部的各個單詞可能會存在的關係。大概來講就是,給定的已知的東西,也要去思考一下會不會對題目答案形成影響。
1.Two Sum
用的暴力的O(n2)
class Solution { public: vector<int> twoSum(vector<int>& nums, int target) { vector<int> ans; for (int i = 0;i < nums.size();i++) { for (int j = i + 1;j < nums.size();j++) { if (nums[i] + nums[j] == target) { ans.push_back(i); ans.push_back(j); return ans; } } } } };
O(n)
沒拿電源進房間要關機了果真沒時間debug都快多啦
class Solution { public: vector<int> twoSum(vector<int>& nums, int target) { vector<int> ans; map<int,int> h; for (int i = 0;i < nums.size();i++) h[target - nums[i]] = -1; for (int i = 0;i < nums.size();i++) { int v = nums[i]; if (h[target - v] != -1) { ans.push_back(h[target - v]); ans.push_back(i); return ans; } h[v] = i; } } };
upd 2018.2.25
後來作到3sum 看到 ksum講解的博客,發現這個能夠排下序,而後掃一遍
class Solution { public: vector<int> twoSum(vector<int>& nums, int target) { vector<int> ans; vector<pair<int,int> > cnum; for (int i = 0;i < nums.size();i++) cnum.push_back(make_pair(nums[i],i)); sort(cnum.begin(),cnum.end()); int l = 0,r = nums.size() - 1; while(l < r) { int sum = cnum[l].first + cnum[r].first; //printf("sum = %d num[%d] = %d num[%d] = %d\n",sum,l,r,nums[l],nums[r]); if (sum == target) { ans.push_back(cnum[l].second),ans.push_back(cnum[r].second); l++;r--; } else if (sum < target) ++l; else --r; } return ans; } };
鏈表
class Solution { public: ListNode* addTwoNumbers(ListNode* l1, ListNode* l2){ ListNode* tail = new ListNode(0); ListNode* p = tail; int add = 0; while(l1 != NULL || l2 != NULL) { int u = 0,v = 0; if(l1 != NULL) {u = l1->val;l1 = l1->next;} if(l2 != NULL) {v = l2->val;l2 = l2->next;} int tmp = u+v+add; p->next = new ListNode(tmp % 10); add = tmp/10; p = p->next; } if(add) p ->next = new ListNode(add); return tail->next; } };
3.Longest Substring Without Repeating Characters
尺取想起某次面試就白板寫這個...沒想到過了快一年要debug這麼久了qaq
class Solution { public: int ok(int* a) { for (int i = 0;i < 128;i++) { if (a[i] > 1) return 0; } return 1; } int lengthOfLongestSubstring(string s) { int vis[128]; memset(vis,0,sizeof(vis)); int len = s.length(),ans = 0; int j = 0; for (int i = 0;i < len;) { while(j < len) { vis[s[j]]++; // printf("i = %d j = %d vis[%c] = %d\n",i,j,s[j],vis[s[j]]); if (!ok(vis)) break; j++; } ans = max(ans,j - i); //printf("i = %d j = %d ans = %d\n",i,j,ans); vis[s[i]]--; //printf("--- vis[%c] = %d\n",s[i],vis[s[i]]); i++;j++; } return ans; } };
判斷ok不ok寫的有點蠢,改進一下qwq
class Solution { public: int ok(int* a) { for (int i = 0;i < 128;i++) { if (a[i] > 1) return 0; } return 1; } int lengthOfLongestSubstring(string s) { int vis[128]; memset(vis,0,sizeof(vis)); int len = s.length(),ans = 0; int i = 0,j = 0; while(i < len && j < len) { // printf("i = %d j = %d vis[%c] = %d\n",i,j,s[j],vis[s[j]]); if (!vis[s[j]]) {vis[s[j]]++; j++;ans = max(ans,j - i);} else {vis[s[i]]--;i++;} } return ans; } };
掃一遍
class Solution { public: double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) { double ans = 0.0; int p = 0,q = 0,cnt = 0,tot = 0; int l1 = nums1.size(),l2 = nums2.size(); vector<int> g;g.clear(); if (nums1.empty()) g = nums2; else if (nums2.empty()) g = nums1; else { while(p < l1 || q < l2) { while((nums1[p] <= nums2[q] && p < l1) || (p < l1 && q == l2)) { g.push_back(nums1[p]); p++; // printf("--- p = %d l1 = %d\n",p,l1); } while((nums2[q] <= nums1[p] && q < l2) || (q < l2 && p == l1)) { g.push_back(nums2[q]); q++; // printf("--- q = %d l2 = %d\n",q,l2); } //printf("p = %d q = %d\n",p,q); } } int len = g.size(); if (len % 2) ans = g[len/2]; else ans = (g[len/2] + g[len/2-1]) * 0.5; return ans; } };
5.Longest Palindromic Substring
最長迴文子串,O(n2)的從中心往兩頭找
class Solution { public: string res = ""; int mx; void ok(string s,int l,int r) { int len = s.length(); while(l >= 0 && r < len) { if (s[l] == s[r]) { if (r - l + 1 > mx) { mx = r - l + 1; res = s.substr(l,r - l + 1); } l--;r++; } else return; } } string longestPalindrome(string s) { mx = 0; if (s.length() == 1) return s; for (int i = 0;i < s.length() - 1;i++) { ok(s,i,i); ok(s,i,i+1); } return res; } };
之
class Solution { public: string convert(string s, int numRows) { string tmp[numRows]; int len = s.length(),cnt = 0; for (;;) { int c1 = 0; while(c1 <= numRows) { tmp[c1] = tmp[c1] + s[cnt]; cnt++; c1++; if (cnt >= len) break; if (c1 >= numRows) break; } if (cnt >= len) break; int c2 = numRows - 2; while(c2 > 0) { tmp[c2] = tmp[c2] + s[cnt]; cnt++; c2--; if (cnt >= len) break; } if (cnt >= len) break; } string ans = ""; for (int i = 0;i < numRows;i++) ans = ans + tmp[i]; return ans; } };
翻轉數字,溢出int輸出0
class Solution { public: int reverse(int x) { int flag = 0; if (x < 0) flag = 1,x = -x; vector<int> ans; while(x) {ans.push_back(x % 10);x = x / 10;} int pos = 0; long long res = 0; for (int i = 0;i < ans.size();i++) { if (ans[i] != '0') { pos = i; break; } } for (int i = pos;i < ans.size();i++) res = res * 10 + ans[i]; if (flag) res = res * -1; if (res > 2147483647) return 0; if (res < -2147483648) return 0; return res; } };
8.
沒讀懂題
迴文數,注意負數沒有迴文數
class Solution { public: bool isPalindrome(int x) { if (x < 0) return false; vector<int> g; int cpx = x; while(x) {g.push_back(x % 10);x = x / 10;} int y = 0; for (int i = 0;i < g.size();i++) y = y * 10 + g[i]; return y == cpx; } };
10.
不會
看題解了...本身寫的時候 是像普通的指針那樣一遍掃過去.. 可是很不對...
從兩頭掃過來
class Solution { public: int maxArea(vector<int>& height) { int ans = 0,len = height.size(); if (len < 2) return 0; int l = 0,r = len - 1; while(l < r) { int tmp = (r - l) * min(height[l],height[r]); // printf("tmp = %d l = %d r = %d \n",tmp,l,r); ans = max(ans,tmp); if (height[l] < height[r]) l++; else r--; } return ans; } };
15.3Sum
發現比題解寫的簡單qwq
class Solution { public: vector<vector<int>> threeSum(vector<int>& nums) { vector<vector<int> > ans; ans.clear(); if (nums.size() < 3) return ans; vector<pair<int,int> >cnums; for (int i = 0;i < nums.size();i++) cnums.push_back(make_pair(nums[i],i)); sort(cnums.begin(),cnums.end()); int len = cnums.size(); set<vector<int> > s; for (int i = 0;i < len;i++) { if (i > 0 && cnums[i].first == cnums[i-1].first) continue; int target = -cnums[i].first; vector<int> tri(3,0); tri[0] = cnums[i].first; int l = i + 1,r = len - 1; while (l < r) { int tmp = cnums[l].first + cnums[r].first; // printf ("i = %d tmp = %d cnums[%d].first = %d cnums[%d].first = %d\n",i,tmp,l,cnums[l].first,r,cnums[r].first); if (tmp == target) { tri[1] = cnums[l].first;tri[2] = cnums[r].first; // ans.push_back(tri); s.insert(tri); l++;r--; } else if (tmp < target) l++; else r--; } } for(set<vector<int> >::iterator it = s.begin();it != s.end();++it) ans.push_back(*it); return ans; } };
16.3Sum Closest
和上題同樣
class Solution { public: int threeSumClosest(vector<int>& nums, int target) { int ans = (1 << 30) - 1,res = (1 << 30) - 1; if (nums.size() < 3) return ans; vector<pair<int,int> >cnums; for (int i = 0;i < nums.size();i++) cnums.push_back(make_pair(nums[i],i)); sort(cnums.begin(),cnums.end()); int len = cnums.size(); set<vector<int> > s; for (int i = 0;i < len;i++) { int l = i + 1,r = len - 1; while (l < r) { int tmp = cnums[l].first + cnums[r].first + cnums[i].first; // printf ("i = %d tmp = %d cnums[%d].first = %d cnums[%d].first = %d %d\n",i,tmp,l,cnums[l].first,r,cnums[r].first,cnums[i].first); int diff = abs(tmp - target); if (diff < ans) { ans = diff; res = tmp; } if (tmp < target) l++; else r--; } } return res; } };
17.Letter Combinations of a Phone Number
暴力
class Solution { public: vector<string> ans; vector<int> g[100]; int len; string str; void dfs(int d,string tmp) { if (d == len) { if (tmp.length() != 0) ans.push_back(tmp); return; } int now = str[d] - '0'; for (int i = 0;i < g[now].size();i++) { char c = g[now][i]; string nxt = tmp + c; dfs(d + 1,nxt); } } vector<string> letterCombinations(string digits) { g[2].push_back('a');g[2].push_back('b');g[2].push_back('c'); g[3].push_back('d');g[3].push_back('e');g[3].push_back('f'); g[4].push_back('g');g[4].push_back('h');g[4].push_back('i'); g[5].push_back('j');g[5].push_back('k');g[5].push_back('l'); g[6].push_back('m');g[6].push_back('n');g[6].push_back('o'); g[7].push_back('p');g[7].push_back('q');g[7].push_back('r');g[7].push_back('s'); g[8].push_back('t');g[8].push_back('u');g[8].push_back('v'); g[9].push_back('w');g[9].push_back('x');g[9].push_back('y');g[9].push_back('z'); len = digits.length(); str = digits; string s = ""; dfs(0,s); return ans; } };
18.4Sum
ksum問題,變成前 k-2層暴力for,最後 兩層 掃一遍
class Solution { public: vector<vector<int>> fourSum(vector<int>& nums, int target) { vector<vector<int> > ans; ans.clear(); if (nums.size() < 4) return ans; vector<pair<int,int> >cnums; for (int i = 0;i < nums.size();i++) cnums.push_back(make_pair(nums[i],i)); sort(cnums.begin(),cnums.end()); int len = cnums.size(); set<vector<int> > s; for (int i = 0;i < len;i++) { for (int j = i + 1;j < len;j++) { int _target = target - cnums[i].first - cnums[j].first; vector<int> tri(4,0); tri[0] = cnums[i].first; tri[1] = cnums[j].first; int l = j + 1,r = len - 1; while (l < r) { int tmp = cnums[l].first + cnums[r].first; // printf ("i = %d tmp = %d cnums[%d].first = %d cnums[%d].first = %d\n",i,tmp,l,cnums[l].first,r,cnums[r].first); if (tmp == _target) { tri[2] = cnums[l].first;tri[3] = cnums[r].first; s.insert(tri); l++;r--; } else if (tmp < _target) l++; else r--; } } } for(set<vector<int> >::iterator it = s.begin();it != s.end();++it) ans.push_back(*it); return ans; } };
-------- 鏈表的昏割線 --------
UPD 2018.5.26 仍是把一個專題的都放在一塊兒叭,也方便之後本身看
19.Remove Nth Node From End of List
刪除鏈表倒數第n個節點
快指針 先走n步,再快慢指針一塊兒走
/** * 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) { if (head == NULL || head->next == NULL) return NULL; ListNode *slow,*fast; slow = head; fast = head; for (int i = 0;i < n;i++) fast = fast->next; if (fast == NULL) return head->next; while(fast->next != NULL) {slow = slow->next;fast = fast->next;} slow->next = slow->next->next; return head; } };
另外一種寫法,遍歷鏈表獲得它的長度,再順序去刪除相應的節點
/** * 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 *p; ListNode *pre; p = head; pre = head; int len = 0; while (p != NULL) p = p->next,len++; p = head; if (len == n) return head->next; for (int i = 1;i < len-n;i++) { p = p->next; } p->next = p->next->next; return head; } };
61.Rotate List
將鏈表 的倒數k個節點放到整個鏈表前面去
快慢指針
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode* rotateRight(ListNode* head, int k) { if (head == NULL) return head; ListNode* cur = head; int n = 0; while (cur != NULL) {n++;cur = cur->next;} k = k % n; ListNode* fast = head; ListNode* slow = head; for (int i = 0;i < k;i++) fast = fast->next; if (fast == NULL) return head; while(fast->next != NULL) { fast = fast->next; slow = slow->next; } fast->next = head; fast = slow->next; slow->next = NULL; return fast; } };
判斷鏈表是否有環,快慢指針
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: bool hasCycle(ListNode *head) { if (head == NULL || head->next == NULL) return false; ListNode *fast,*slow; fast = head;slow = head; while (fast != NULL) { fast = fast->next; if (fast == NULL) break; fast = fast->next; slow = slow->next; if (slow == NULL) break; if (fast == slow) return true; } return false; } };
帶有環的鏈表,求出環的起點。好像大三的時候作,總是不能理解快慢指針相遇以後,用快指針按照一次一步,和位於head的指針一次一步,同時走,相遇點就是環的起點
作了下面那題以後,就能夠這樣想,將這個有環的鏈表從相遇點斷開,那麼環的起始點就是兩條鏈表的相遇點,並且這兩條鏈表在相遇以前的部分是等長的,就不須要下一題的第一步工做
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode *detectCycle(ListNode *head) { if (head == NULL || head->next == NULL) return NULL; ListNode *fast,*slow; fast = head;slow = head; while (fast != NULL) { fast = fast->next; if (fast == NULL) return NULL; fast = fast->next; slow = slow->next; if (slow == NULL) return NULL; if (fast == slow) break; } ListNode* p; p = head; while (fast != NULL) { if (fast == p) return p; fast = fast->next; p = p->next; if (p == NULL) return NULL; } return NULL; } };
160.Intersection of Two Linked Lists
求兩個鏈表的交點,先分別求出兩個鏈表的長度,長度之差記爲len 更長的先走len,再一塊兒走,相遇的節點就是相交的節點
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) { if (headA == NULL || headB == NULL) return NULL; ListNode *h1,*h2; h1 = headA;h2 = headB; int len1 = 0,len2 = 0; while (h1->next != NULL) {h1 = h1->next;len1++;} while (h2->next != NULL) {h2 = h2->next;len2++;} h1 = headA;h2 = headB; if (len1 > len2) {for (int i = 1;i <= len1-len2;i++) h1 = h1->next;} else {for (int i = 1;i <= len2 - len1;i++) h2 = h2->next;} //printf("len1 = %d len2 = %d\n",len1,len2); while (h1 != NULL && h2 != NULL) { if (h1 == h2) return h1; h1 = h1->next; h2 = h2->next; } return NULL; } };
237.Delete Node in a Linked List
從鏈表中刪除一個節點.. qaq不會... 由於一直以來刪除鏈表的一個節點都會想着將當前節點的後繼連在前驅節點後面
可是這題,是隻給出了須要刪除的節點,全部,能夠先把它後面那個節點拷貝給它,就至關於刪去了這個節點qaq
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: void deleteNode(ListNode* node) { node->val = node->next->val; node->next = node->next->next; } };
xxx.
給定一個鏈表中的節點,向它前面插入一個節點(由於按照一篇鏈表總結的博客來作題,沒有搜到相應的leetcode,就只能本地本身實現一下
和上一題很同樣的想法,將節點p的東西拷貝到新插入的節點q中,再將本該是q的value的東西放到p裏面
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <ctime> using namespace std; struct ListNode { int val; ListNode* nxt; ListNode(int x):val(x),nxt(NULL) {} }; void addToTail(ListNode **head,int val) { ListNode* node = new ListNode(val); if (!*head) {*head = node;} else { ListNode *tmp = *head; while (tmp->nxt) tmp = tmp->nxt; tmp->nxt = node; } } void printList(ListNode* head) { ListNode* tmp; tmp = head; if (tmp == NULL) cout << "empty list"; else { while (tmp != NULL) { cout << tmp->val << ','; tmp = tmp->nxt; } cout << "\n"; } } ListNode* process(ListNode* head) { ListNode* p; p = head; for (int i = 1;i <= 3 ;i++) {p = p->nxt;printf("i = %d\n",i);} ListNode* q = new ListNode(p->val); q->nxt = p->nxt; p->nxt = q; p->val = 5555; return head; } int main() { srand(19950635); int len = 6; ListNode* root = NULL; for (int i = 0;i < len;i++) addToTail(&root,rand() % 10); printList(root); ListNode* newhead; newhead = process(root); printList(newhead); return 0; }
xxx.
給定一個鏈表,在某個節點前面插入一個新的節點.. 這個的想法就很天然了
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <ctime> using namespace std; struct ListNode { int val; ListNode* nxt; ListNode(int x):val(x),nxt(NULL) {} }; void addToTail(ListNode **head,int val) { ListNode* node = new ListNode(val); if (!*head) {*head = node;} else { ListNode *tmp = *head; while (tmp->nxt) tmp = tmp->nxt; tmp->nxt = node; } } void printList(ListNode* head) { ListNode* tmp; tmp = head; if (tmp == NULL) cout << "empty list"; else { while (tmp != NULL) { cout << tmp->val << ','; tmp = tmp->nxt; } cout << "\n"; } } ListNode* process(ListNode* head) { ListNode* p; p = head; for (int i = 1;i <= 2 ;i++) {p = p->nxt;printf("p[%d].val = %d\n",i,p->val);} ListNode* q = new ListNode(5555); q->nxt = p->nxt; p->nxt = q; return head; } int main() { srand(19950635); int len = 6; ListNode* root = NULL; for (int i = 0;i < len;i++) addToTail(&root,rand() % 10); printList(root); ListNode* newhead; newhead = process(root); printList(newhead); return 0; }
138.Copy List with Random Pointer
鏈表的深拷貝...很新鮮的一道題目! 網上題解的圖表達得很清晰
/** * Definition for singly-linked list with a random pointer. * struct RandomListNode { * int label; * RandomListNode *next, *random; * RandomListNode(int x) : label(x), next(NULL), random(NULL) {} * }; */ class Solution { public: RandomListNode *copyRandomList(RandomListNode *head) { if (head == NULL) return NULL; RandomListNode *h; h = head; while (h != NULL) { RandomListNode* copy = new RandomListNode(h->label); RandomListNode* next = h->next; h->next = copy; copy->next = next; h = next; } h = head; while (h != NULL) { if (h->random != NULL) h->next->random = h->random->next; h = h->next->next; } h = head; RandomListNode* newHead = h->next; while (h != NULL) { RandomListNode* copy = h->next; h->next = copy->next; h = h->next; if (h != NULL) copy->next = h->next; else copy->next = NULL; } return newHead; } };
另外一種更直觀的作法,把原節點和copy節點放在map裏面,最後再遍歷一遍copy鏈表,去map裏面找到它的random
/** * Definition for singly-linked list with a random pointer. * struct RandomListNode { * int label; * RandomListNode *next, *random; * RandomListNode(int x) : label(x), next(NULL), random(NULL) {} * }; */ class Solution { public: RandomListNode *copyRandomList(RandomListNode *head) { if (head == NULL) return NULL; RandomListNode *res = new RandomListNode(head->label); RandomListNode *node = res; RandomListNode* cur = head->next; map<RandomListNode*,RandomListNode*> m; m[head] = res; while (cur) { RandomListNode *tmp = new RandomListNode(cur->label); node->next = tmp; m[cur] = tmp; node = node->next; cur = cur->next; } node = res;cur = head; while (node) { node->random = m[cur->random]; node = node->next; cur = cur->next; } return res; } };
合併兩個有序的鏈表
/** * 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) { ListNode *head = new ListNode(0); ListNode *p;p = head; while (l1 != NULL && l2 != NULL) { if (l1->val < l2->val) { //printf("11111\n"); ListNode* tmp = new ListNode(l1->val); p->next = tmp; l1 = l1->next; } else { //printf("222222\n"); ListNode* tmp = new ListNode(l2->val); p->next = tmp; l2 = l2->next; } //printf("p->val = %d\n",p->val); p = p->next; } if (l1 != NULL) p->next = l1; if (l2 != NULL) p->next = l2; return head->next; } };
合併k個有序的鏈表,分治
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ /** * 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) { ListNode *headdummy = new ListNode(0); ListNode *p; p = headdummy; while (l1 != NULL && l2 != NULL) { if (l1->val >= l2->val) p->next = l2, l2 = l2->next; else p->next = l1, l1 = l1->next; p = p->next; } if (l1 != NULL) p->next = l1; if (l2 != NULL) p->next = l2; return headdummy->next; } ListNode* mergeKLists(vector<ListNode*>& lists) { if (lists.empty()) return NULL; while(lists.size() > 1) { lists.push_back(mergeTwoLists(lists[0], lists[1])); lists.erase(lists.begin()); lists.erase(lists.begin()); } return lists.front(); } };
143.Reorder List
將鏈表按照這樣的順序排列出來L1 Ln L2 Ln-1 ....
最開始本身想的是將整個鏈表翻轉,再和原來鏈表輪流放,可是好像 翻轉以後,原來的head 就變成尾指針了
因而看題解,先找到 中間的節點,將右邊的所有翻轉,再依次放
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode* rotate(ListNode* head) { if (head == NULL || head->next == NULL) return head; ListNode *p,*q; p = head; q = NULL; while (p != NULL) { ListNode* cur = p->next; p->next = q; q = p; p = cur; } return q; } ListNode* findmid(ListNode* head) { ListNode *fast = head->next; ListNode *slow = head; while (fast != NULL && fast->next != NULL) { slow = slow->next; fast = fast->next->next; } return slow; } void merge(ListNode *&left,ListNode *&right) { ListNode *head = (ListNode *)malloc(sizeof(ListNode)); ListNode *res = head; int cnt = 0; while (left != NULL && right != NULL) { if ((cnt % 2) == 0) { head->next = left; left = left->next; } else { head->next = right; right = right->next; } head = head->next; cnt++; } if (left != NULL) head->next = left; if (right != NULL) head->next = right; left = res->next; } void reorderList(ListNode* head) { if (head == NULL || head->next == NULL) return; ListNode *mid; mid = findmid(head); ListNode *tail = rotate(mid->next); mid->next = NULL; merge(head,tail); } };
鏈表分紅k個部分,翻轉再鏈接起來
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode* Rotate(ListNode* head) { if (head == NULL || head->next == NULL) return head; ListNode *p,*q; p = head; q = NULL; while (p != NULL) { ListNode* cur = p->next; p->next = q; q = p; p = cur; } return q; } int ListLength(ListNode *head) { if (head == NULL) return 0; int cnt = 0; while (head != NULL) { cnt++; head = head->next; } return cnt; } ListNode* ListAppend(ListNode *first,ListNode *second) { if (first == NULL) return second; ListNode *res = first; while (res->next != NULL) res = res->next; res->next = second; return first; } void printList(ListNode* head) { ListNode* tmp; tmp = head; if (tmp == NULL) cout << "empty list" << "\n"; else { while (tmp != NULL) { cout << tmp->val << ','; tmp = tmp->next; } cout << "\n"; } } ListNode* reverseKGroup(ListNode* head, int k) { if (k == 1 || k == 0 || head == NULL || head->next == NULL) return head; int len = ListLength(head); if (k > len) return head; ListNode *p = head; ListNode *res = NULL; while (p != NULL) { int cnt = 1; ListNode *tmp = p; while (cnt < k && tmp != NULL) tmp = tmp->next,cnt++; if (tmp == NULL) {res = ListAppend(res,p);break;} ListNode *pnxt = tmp->next; tmp->next = NULL; ListNode *tail = Rotate(p); res = ListAppend(res,tail); p = pnxt; } return res; } };
83.Remove Duplicates from Sorted List
刪除有序鏈表中value重複的節點
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: void printList (ListNode* head) { if (head == NULL) printf("empty\n"); else { while (head != NULL) { printf("%d ",head->val); head = head->next; } printf("\n"); } } ListNode* deleteDuplicates(ListNode* head) { if (head == NULL || head->next == NULL) return head; ListNode *p,*pre; p = head->next; pre = head; int val = head->val; while (p != NULL) { while (p != NULL && p->val == val) {p = p->next;} pre->next = p; if (p == NULL) break; val = p->val; pre = pre->next; p = p->next; } return head; } };
兩個長度不同的鏈表 相加 可是這個高位在鏈表的頭,若是翻轉鏈表 就和以前那題相加 同樣 ,用棧 實現 從低位到高位加,而後依次把節點放在前面
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: int ListLength(ListNode* head) { if (head == NULL) return 0; int cnt = 0; while (head != NULL) {cnt++;head = head->next;} return cnt; } void printList(ListNode *head) { if (head == NULL) printf("empty\n"); else { while(head != NULL) {printf("%d ",head->val);} printf("\n"); } } ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) { if (l1 == NULL && l2 == NULL) return NULL; stack<int> s1; stack<int> s2; while (l1 != NULL) {s1.push(l1->val);l1 = l1->next;} while (l2 != NULL) {s2.push(l2->val);l2 = l2->next;} ListNode *res = new ListNode(0); int add = 0; while (!s1.empty() || !s2.empty()) { int u = 0,v = 0; if (!s1.empty()) {u = s1.top();s1.pop();} if (!s2.empty()) {v = s2.top();s2.pop();} res->val = (u + v + add) % 10; ListNode *head = new ListNode((u + v + add) / 10); head->next = res; res = head; add = (u + v + add) / 10; } if (res->val == 0) return res->next; return res; return res; } };
交換相鄰兩個節點的鏈表,注意交換兩個節點的時候,要考慮到它們先後鏈接關係的改變
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode* swapPairs(ListNode* head) { if (head == NULL || head->next == NULL) return head; ListNode *p = head; ListNode *res = new ListNode(-1); ListNode *ptr = res; while (p != NULL) { if (p->next != NULL) { ListNode *q = p->next; ptr->next = q; p->next = q->next; q->next = p; ptr = p; } else { ptr->next = p; } p = p->next; } return res->next; } };
另外一種寫法
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode* swapPairs(ListNode* head) { if (head == NULL || head->next == NULL) return head; ListNode *p, *pre, *mid; ListNode *dummyhead = new ListNode(-1); dummyhead->next = head; p = dummyhead->next; pre = dummyhead; while (p != NULL) { mid = p; p = p->next; if (p == NULL) break; //swap mid->next = p->next; pre->next = p; p->next = mid; p = mid->next; pre = mid; } return dummyhead->next; } };
判斷是不是迴文鏈表,找中點,翻轉右邊,再挨個比較
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode* FindMid(ListNode* head) { ListNode *slow = head,*fast = head->next; while (fast != NULL && fast->next != NULL) { fast = fast->next->next; slow = slow->next; } return slow; } ListNode* reverse(ListNode *head) { if (head == NULL || head->next == NULL) return head; ListNode *p = head,*q = NULL; while (p != NULL) { ListNode *cur = p->next; p->next = q; q = p; p = cur; } return q; } void PrintList(ListNode* head) { if (head == NULL) printf("empty\n"); while (head != NULL) {printf("%d ",head->val);head = head->next;} printf("\n"); } bool isPalindrome(ListNode* head) { if (head == NULL || head->next == NULL) return true; ListNode *mid = FindMid(head); ListNode *right = mid->next; right = reverse(right);mid->next = NULL; PrintList(right); ListNode *p = head,*q = right; while (p != NULL && q != NULL) { if (p->val != q->val) return false; p = p->next; q = q->next; } return true; } };
鏈表奇的放前面,偶的部分放後面
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: void PrintList(ListNode*head) { if (head == NULL) printf("empty\n"); else { while(head != NULL) { printf("%d ",head->val); head = head->next; } printf("\n"); } } ListNode* oddEvenList(ListNode* head) { if (head == NULL || head->next == NULL) return head; ListNode *odd = head,*even = head->next; ListNode *evenhead = even; while (even != NULL && even->next != NULL) { odd->next = odd->next->next; odd = odd->next; even->next = even->next->next; even = even->next; } odd->next = evenhead; PrintList(odd); return head; } };
數組排序算法
1. 冒泡排序
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int maxn = 1e5 + 5; int a[maxn],n; void bubblesort() { for (int i = 1;i <= n;i++) { for (int j = 1;j <= n-i;j++) { if (a[j+1] > a[j]) swap(a[j], a[j+1]); } } } int main() { scanf("%d",&n); for (int i = 1;i <= n;i++) scanf("%d",&a[i]); bubblesort(); for (int i = 1;i <= n;i++) printf("%d ",a[i]); printf("\n"); return 0; }
2.選擇排序
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int maxn = 1e5 + 5; int a[maxn],n; void selectsort() { for (int i = 1;i <= n;i++) { int mn = a[i],id = i; for (int j = i;j <= n;j++) { if (a[j] < mn) { mn = a[j]; id = j; } } if (id != i) swap(a[i], a[id]); } } int main() { scanf("%d",&n); for (int i = 1;i <= n;i++) scanf("%d",&a[i]); selectsort(); for (int i = 1;i <= n;i++) printf("%d ",a[i]); printf("\n"); return 0; }
3.快排
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int maxn = 1e5 + 5; int a[maxn],n; int split(int arr[], int left, int right) { int pivot = arr[(left+right)/2]; while (left <= right) { while (arr[left] < pivot) left++; while (arr[right] > pivot) right--; if (left <= right) { swap(arr[left], a[right]); left++; right--; } } return left; } void quicksort(int arr[], int left, int right) { int index = split(arr, left, right); if (left < index - 1) quicksort(arr, left, index-1); if (index < right) quicksort(arr, index, right); } int main() { scanf("%d",&n); for (int i = 1;i <= n;i++) scanf("%d",&a[i]); quicksort(a, 1, n); for (int i = 1;i <= n;i++) printf("%d ",a[i]); printf("\n"); return 0; }
4.基數排序
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int maxn = 1e5 + 5; int a[maxn],n, c[maxn],bucket[maxn]; int getdigit(int x, int d) { int ans = 0; while(d--) { ans = x % 10; x = x / 10; } return ans; } int caldigit(int x) { int ans = 0; while(x) { ans++; x = x/10; } return ans; } void radixsort() { int digit = 0; for (int i = 1;i <= n;i++) digit = max(digit, caldigit(a[i])); for (int k = 1;k <= digit;k++) { for (int i = 0; i < 10;i++) c[i] = 0; for (int i = 1;i <= n;i++) { int now = getdigit(a[i], k); c[now]++; } for (int i = 0;i < 10;i++) c[i] = c[i-1] + c[i]; for (int i = n;i >= 1;i--) { int now = getdigit(a[i],k); bucket[c[now]] = a[i]; c[now]--; } for (int i = 1;i <= n;i++) printf("%d ",bucket[i]); printf("\n"); for (int i = 1;i <= n;i++) a[i] = bucket[i]; } } int main() { scanf("%d",&n); for (int i = 1;i <= n;i++) scanf("%d",&a[i]); radixsort(); for (int i = 1;i <= n;i++) printf("%d ",a[i]); printf("\n"); return 0; } /* 5 35 23 536 1024 1536 */
5. 歸併排序
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int maxn = 1e5 + 5; int n, a[maxn], t[maxn]; void mergesort(int* A, int x, int y, int* T) { if (y-x > 1) { int m = x + (y - x)/2; int p = x, q = m, i = x; mergesort(A, x, m, T); mergesort(A, m, y, T); while (p < m || q <= y) { if (q > y || (p < m && a[p] <= a[q])) T[i++] = a[p++]; else T[i++] = a[q++]; } for (i = x;i <= y;i++) a[i] = T[i]; } } int main() { scanf("%d",&n); for (int i = 1;i <= n;i++) scanf("%d", &a[i]); mergesort(a, 1, n, t); for (int i = 1;i <= n;i++) printf("%d ", a[i]); printf("\n"); for (int i = 1;i <= n;i++) printf("%d ", t[i]); printf("\n"); return 0; }
6. 插入排序
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int maxn = 1e5 + 5; int n, a[maxn], t[maxn]; void insertsort() { for (int i = 1;i <= n;i++) { int tmp = a[i]; int j; for (j = i-1;j >= 1 && tmp < a[j];j--) { a[j+1] = a[j]; } a[j+1] = tmp; } } int main() { scanf("%d",&n); for (int i = 1;i <= n;i++) scanf("%d", &a[i]); insertsort(); for (int i = 1;i <= n;i++) printf("%d ", a[i]); printf("\n"); return 0; } /* 6 2 1 5 6 3 4 7 2 1 1 5 3 6 4 */
7. 堆排
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <vector> using namespace std; const int maxn =1e6 + 5; int n,a[maxn]; vector<int> heap; // UP void push(int x) { int now = heap.size(); heap.push_back(x); while (now > 0) { int fa = (now-1)/2; if (heap[fa] <= heap[now]) break; swap(heap[fa],heap[now]); now = fa; } } int top() { return heap[0]; } // down int pop() { int ans = heap[0]; int sz = heap.size(); swap(heap[0],heap[--sz]); heap.pop_back(); int index = 0; while (index*2 + 1 < sz) { int right = index*2 + 1; int left = index*2 + 2; int min_index = index; if (right < sz && heap[right] < heap[min_index]) { min_index = right; } if (left < sz && heap[left] < heap[min_index]) { min_index = left; } if (min_index == index) break; swap(heap[min_index],heap[index]); index = min_index; } return ans; } int main() { scanf("%d",&n); for (int i = 1;i <= n;i++) scanf("%d",&a[i]); for (int i = 1;i <= n;i++) { push(a[i]); } for (int i = 1;i <= n;i++) { int tmp = top(); pop(); printf("%d",tmp); if (i != n) printf(" "); else printf("\n"); } return 0; }
鏈表排序
快排
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode* partitionList(ListNode* lowPre, ListNode* low, ListNode* high) { int key = low->val; ListNode node1(0), node2(0); ListNode *small = &node1, *big = &node2; for(ListNode *i = low->next; i != high; i = i->next) { if (i->val < key) { small->next = i; small = i; } else { big->next = i; big = i; } } big->next = high; small->next = low; low->next = node2.next; lowPre->next = node1.next; return low; } void qsortList(ListNode* headPre, ListNode* head, ListNode* tail) { if(head != tail && head->next != tail) { ListNode* mid = partitionList(headPre, head, tail); qsortList(headPre, headPre->next,mid); qsortList(mid,mid->next,tail); } } ListNode* sortList(ListNode* head) { if (head == NULL || head->next == NULL) return head; ListNode tmpHead(0);tmpHead.next = head; qsortList(&tmpHead, head, NULL); return tmpHead.next; } };
歸併排序
class Solution { public: ListNode* merge(ListNode*head1, ListNode*head2) { if (head1 == NULL) return head2; if (head2 == NULL) return head1; ListNode *res, *p; if (head1->val < head2->val) res = head1,head1 = head1->next; else res = head2,head2 = head2->next; p = res; while (head1!= NULL && head2 != NULL) { if (head1->val < head2->val) p->next = head1,head1 = head1->next; else p->next = head2,head2 = head2->next; p = p->next; } if (head2 != NULL) p->next = head2; if (head1 != NULL) p->next = head1; return res; } ListNode* sortList(ListNode* head) { if (head == NULL || head->next == NULL) return head; ListNode *fast, *slow; fast = head;slow = head; while (fast->next != NULL && fast->next->next != NULL) { slow = slow->next; fast = fast->next->next; } fast = slow; slow = slow->next; fast->next = NULL; fast = sortList(head); slow = sortList(slow); return merge(fast,slow); } };
從尾到頭打印鏈表
/** * struct ListNode { * int val; * struct ListNode *next; * ListNode(int x) : * val(x), next(NULL) { * } * }; */ class Solution { public: vector<int> ans; void PrintListR(ListNode* pHead) { if (pHead != NULL) { if (pHead->next != NULL) { PrintListR(pHead->next); } ans.push_back(pHead->val); } } vector<int> printListFromTailToHead(ListNode* head) { PrintListR(head); return ans; } };