这篇用来放作的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; } };