CodeTop题解
CodeTop 第一页
206. 反转链表 - 力扣(LeetCode) (leetcode-cn.com)
1 class Solution { 2 public: 3 ListNode* reverse(ListNode* pre,ListNode* head) { 4 if(head==nullptr) 5 return pre; 6 ListNode *beh = head->next; 7 head->next = pre; 8 pre = head; 9 head = beh; 10 return reverse(pre,head); 11 } 12 ListNode* reverseList(ListNode* head) { 13 return reverse(nullptr,head); 14 } 15 };
146. LRU 缓存 - 力扣(LeetCode) (leetcode-cn.com)
因为removeNode,修改了tail->pre的指向,这时候用tail->pre会报错
1 class LRUCache { 2 public: 3 struct LinkNode{ 4 int key,val; 5 struct LinkNode *pre; 6 struct LinkNode *next; 7 LinkNode():key(0),val(0),pre(nullptr),next(nullptr){} 8 LinkNode(int key,int val):key(key),val(val),pre(nullptr),next(nullptr){} 9 }; 10 LinkNode* head; 11 LinkNode* tail; 12 unordered_map<int ,LinkNode*> map; 13 int capacity; 14 LRUCache(int _capacity):capacity(_capacity) { 15 head = new LinkNode(); 16 tail = new LinkNode(); 17 head->next = tail; 18 tail->pre = head; 19 } 20 21 int get(int key) { 22 if(map.count(key)==0) 23 return -1; 24 removeNode(map[key]); 25 addToHead(map[key]); 26 return map[key]->val; 27 } 28 29 void put(int key, int value) { 30 if(map.count(key)==0){ 31 LinkNode* node = new LinkNode(key,value); 32 map[key] = node; 33 addToHead(node); 34 if(map.size()>capacity){ 35 LinkNode* delNode = tail->pre; 36 removeNode(tail->pre); 37 map.erase(delNode->key);//这里要使用另外定义delNode,用tail->pre报错 38 delete delNode;//这里要使用另外定义delNode,用tail->pre报错 39 } 40 }else{ 41 map[key]->val = value; 42 removeNode(map[key]); 43 addToHead(map[key]); 44 } 45 } 46 void removeNode(LinkNode* node){ 47 node->pre->next = node->next; 48 node->next->pre = node->pre; 49 } 50 void addToHead(LinkNode* node){ 51 node->next = head->next; 52 node->pre = head; 53 head->next = node; 54 node->next->pre = node; 55 56 } 57 };
3. 无重复字符的最长子串 - 力扣(LeetCode) (leetcode-cn.com)
二刷代码更好了,初始化方面老忘记。
1 class Solution { 2 public: 3 int lengthOfLongestSubstring(string s) { 4 if(s.size() == 0) 5 return 0; 6 unordered_map<char,int> map; 7 vector<int> dp(s.size(),0); 8 dp[0] = 1; 9 map[s[0]] = 0;//初始化忘记了 10 int start = 0; 11 int ans = 1;//初始化1 12 for(int i=1;i<s.size();i++){ 13 if(map.count(s[i]) == 0){ 14 dp[i] = dp[i-1]+1; 15 }else{ 16 start = max(start,map[s[i]]+1); 17 dp[i] = i-start+1; 18 } 19 map[s[i]] = i; 20 ans = max(ans,dp[i]); 21 } 22 return ans; 23 } 24 };
215. 数组中的第K个最大元素 - 力扣(LeetCode) (leetcode-cn.com)
这道题各种排序解法写在排序算法里
1 class Solution {//parent = (son-1)/2 lson = parent*2+1 rson = parent*2+2 2 public: 3 void adjust(vector<int>&nums,int n,int index){//递归调整当前节点 4 if(index>=n) 5 return; 6 int lson = index*2+1,rson = index*2+2; 7 int mn = index; 8 if(lson<n&&nums[lson]<nums[mn]){//堆是大还是小就看这里符号 9 mn = lson; 10 } 11 if(rson<n&&nums[rson]<nums[mn]){ 12 mn = rson; 13 } 14 if(mn!=index){ 15 swap(nums[mn],nums[index]); 16 adjust(nums,n,mn); 17 } 18 } 19 void build_heap(vector<int>&nums,int n){//小根堆,排序后是从大到小 20 int last_node = n-1; 21 int last_parent = (last_node-1)/2; 22 for(int i=last_parent;i>=0;i--){//从最后一个节点的父节点(即最后一个非叶子节点进行调整) 23 adjust(nums,n,i); 24 } 25 } 26 void hsort(vector<int>&nums,int n){//在数组已经是堆的基础之上,拿到最小值赋值到数组末尾,调整堆顶, 27 build_heap(nums,n); 28 for(int i=n-1;i>=0;i--){ 29 swap(nums[i],nums[0]); 30 adjust(nums,i,0); 31 } 32 } 33 int findKthLargest(vector<int>& nums, int k) { 34 int n=nums.size(); 35 hsort(nums,n); 36 for(int i=0;i<nums.size();i++) 37 cout<<nums[i]<<" "; 38 return nums[k-1]; 39 } 40 };
25. K 个一组翻转链表 - 力扣(LeetCode) (leetcode-cn.com)
1 class Solution { 2 public: 3 ListNode* reverseKGroup(ListNode* head, int k) { 4 ListNode *t =head; 5 for(int i=0;i<k;i++){ 6 if(t==nullptr) 7 return head; 8 t=t->next; 9 } 10 ListNode *pre = head; 11 ListNode *cur = head->next; 12 for(int i=0;i<k-1;i++){ 13 14 cur->next = pre; 15 pre = cur; 16 cur = nextcur; 17 } 18 ListNode* next = reverseKGroup(cur,k); 19 head->next = next; 20 return pre ; 21 } 22 };
15. 三数之和 - 力扣(LeetCode) (leetcode-cn.com)
1 class Solution { 2 public: 3 vector<vector<int>> threeSum(vector<int>& nums) { 4 vector<vector<int>> result; 5 sort(nums.begin(),nums.end()); 6 for(int i=0;i<nums.size()&&nums[i]<=0;i++){ 7 if(i>0&&nums[i]==nums[i-1]){//对a去重 8 continue ; 9 } 10 int target = -nums[i]; 11 int left = i+1,right = nums.size()-1;//left和right是下标不是nums[i+1] 12 while(left<right){ 13 if(nums[left]+nums[right]==target){ 14 result.push_back(vector<int>{nums[i],nums[left],nums[right]}); 15 left++;//忘记加 16 right--; 17 while (right > left && nums[right] == nums[right + 1]) right--;//对b去重 忘记了 18 while (right > left && nums[left] == nums[left - 1]) left++;//对c去重 19 }else if(nums[left]+nums[right]<target){ 20 left++; 21 }else if(nums[left]+nums[right]>target){ 22 right--; 23 } 24 } 25 } 26 return result; 27 } 28 };
912. 排序数组 - 力扣(LeetCode) (leetcode-cn.com)
1 class Solution { 2 public: 3 void qsort(vector<int>&nums,int left,int right){ 4 if(left>=right) 5 return ; 6 int cmp = left,j=left; 7 int randnum = rand() % (right - left + 1) + left; // 随机选一个作为我们的cmp,思路:选好了和left交换。不要把随机数直接作为cmp 8 swap(nums[left], nums[randnum]); 9 for(int i=left+1;i<=right;++i){ 10 if(nums[i]<nums[cmp]){//这里小于或者小于等于都行 11 swap(nums[++j],nums[i]); 12 } 13 } 14 swap(nums[cmp],nums[j]); 15 qsort(nums,left,j-1);//这里是j 16 qsort(nums,j+1,right); 17 } 18 vector<int> sortArray(vector<int>& nums) { 19 qsort(nums,0,nums.size()-1); 20 return nums; 21 } 22 };
53. 最大子数组和 - 力扣(LeetCode) (leetcode-cn.com)
1 class Solution { 2 public: 3 int maxSubArray(vector<int>& nums) { 4 int ans=nums[0],sum = 0; 5 for(int i=0;i<nums.size();i++){ 6 sum = sum+nums[i]; 7 ans = max(ans,sum);//先计入答案,再操作sum 8 sum=max(0,sum); 9 10 } 11 return ans; 12 } 13 };
21. 合并两个有序链表 - 力扣(LeetCode) (leetcode-cn.com)
1 class Solution { 2 public: 3 ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) { 4 ListNode* head = new ListNode(); 5 ListNode *t = head; 6 while(list1&&list2){ 7 if(list1->val<=list2->val){ 8 t->next = list1; 9 list1 = list1->next; 10 } 11 else{ 12 t->next = list2; 13 list2 = list2->next; 14 } 15 t=t->next; 16 } 17 while(list1){ 18 t->next = list1; 19 list1 = list1->next; 20 t = t->next; 21 } 22 while(list2){ 23 t->next = list2; 24 list2 = list2->next; 25 t = t->next; 26 } 27 return head->next; 28 } 29 };
1. 两数之和 - 力扣(LeetCode) (leetcode-cn.com)
1 class Solution { 2 public: 3 vector<int> twoSum(vector<int>& nums, int target) { 4 unordered_map<int,int> a;//key是值,value是数组下标 5 for(int i=0;i<nums.size();i++){ 6 if(a.count(target-nums[i])){ 7 return{i,a[target-nums[i]]}; 8 }else{ 9 a[nums[i]]=i;//a.insert(make_pair(nums[i],i)); 10 } 11 } 12 return {}; 13 } 14 };
102. 二叉树的层序遍历 - 力扣(LeetCode) (leetcode-cn.com)
1 class Solution { 2 public: 3 void pre(TreeNode* root,int depth,vector<vector<int>>&ans){ 4 if(root==NULL) 5 return ; 6 if(depth>=ans.size()) 7 ans.push_back(vector<int>{}); 8 ans[depth].push_back(root->val); 9 pre(root->left,depth+1,ans); 10 pre(root->right,depth+1,ans); 11 } 12 vector<vector<int>> levelOrder(TreeNode* root) { 13 vector<vector<int>> ans; 14 pre(root, 0, ans); 15 return ans; 16 } 17 };
141. 环形链表 - 力扣(LeetCode) (leetcode-cn.com)
1 class Solution { 2 public: 3 bool hasCycle(ListNode *head) { 4 if(head==NULL) 5 return false; 6 ListNode* fast = head->next; 7 ListNode* slow = head; 8 while(fast!=NULL&&fast->next!=NULL){ 9 if(slow==fast) 10 return true; 11 slow = slow->next; 12 fast = fast->next->next; 13 } 14 return false; 15 } 16 };
121. 买卖股票的最佳时机 - 力扣(LeetCode) (leetcode-cn.com)
1 class Solution { 2 public: 3 int maxProfit(vector<int>& prices) {//dp数组的dp[i]表示那天卖出的利润,所以维护在此之前最小值就行 4 int ans = 0; 5 vector<int>dp(prices.size()); 6 dp[0] = prices[0]; 7 for(int i=1;i<prices.size();i++){ 8 dp[i] = min(dp[i-1],prices[i]); 9 ans = max(ans,prices[i]-dp[i]); 10 } 11 return ans; 12 } 13 };
160. 相交链表 - 力扣(LeetCode) (leetcode-cn.com)
1 class Solution { 2 public: 3 ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) { 4 ListNode *PA = headA; 5 ListNode *PB = headB; 6 while(PA!=PB){ 7 if(PA) 8 PA = PA->next; 9 else 10 PA = headB; 11 if(PB) 12 PB = PB->next; 13 else 14 PB = headA; 15 } 16 return PA; 17 } 18 };
103. 二叉树的锯齿形层序遍历 - 力扣(LeetCode) (leetcode-cn.com)
1 class Solution { 2 public: 3 vector<vector<int>> zigzagLevelOrder(TreeNode* root) { 4 if(!root) 5 return {}; 6 vector<vector<int>> result; 7 queue<TreeNode*>que; 8 int depth = 1; 9 que.push(root); 10 while(!que.empty()){ 11 vector<int>path; 12 int n = que.size(); 13 for(int i=0;i<n;i++){ 14 TreeNode* t = que.front(); 15 que.pop(); 16 path.push_back(t->val); 17 if(t->left) 18 que.push(t->left); 19 if(t->right) 20 que.push(t->right); 21 } 22 if(depth%2==0){ 23 for(int i=0,j=path.size()-1;i<j;i++,j--){ 24 int temp = path[i]; 25 path[i] = path[j]; 26 path[j] = temp; 27 } 28 } 29 result.push_back(path); 30 depth++; 31 } 32 return result; 33 } 34 };
20. 有效的括号 - 力扣(LeetCode) (leetcode-cn.com)
1 class Solution { 2 public: 3 bool isValid(string s) { 4 unordered_map<char,char>map = { 5 {')','('},{'}','{'},{']','['} 6 }; 7 stack<char> st; 8 for(int i=0;i<s.size();i++){ 9 if(s[i]==')'||s[i]=='}'||s[i]==']'){ 10 if(!st.empty()&&st.top()==map[s[i]]){ 11 st.pop(); 12 } 13 else 14 return false; 15 }else 16 st.push(s[i]); 17 } 18 return st.empty(); 19 } 20 };
88. 合并两个有序数组 - 力扣(LeetCode) (leetcode-cn.com)
1 class Solution { 2 public: 3 void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) { 4 int i=m-1,j=n-1,k=m+n-1; 5 while(i>=0&&j>=0){ 6 if(nums1[i]>=nums2[j]) 7 nums1[k--] = nums1[i--]; 8 else 9 nums1[k--] = nums2[j--]; 10 11 } 12 while(i>=0){ 13 nums1[k--] = nums1[i--]; 14 } 15 while(j>=0){ 16 nums1[k--] = nums2[j--]; 17 } 18 } 19 };
236. 二叉树的最近公共祖先 - 力扣(LeetCode) (leetcode-cn.com)
1 class Solution { 2 public: 3 TreeNode* f(TreeNode* root, TreeNode* p, TreeNode* q){//没有父母parent这个指针,只能通过返回值给父母,nice 4 if(!root) 5 return NULL; 6 if(root==p||root==q)//父子 7 return root; 8 root->left = f(root->left,p,q); 9 root->right = f(root->right,p,q); 10 if(root->left&&root->right)//兄弟情况 11 return root; 12 return root->left?root->left:root->right; 13 } 14 TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { 15 return f(root,p,q); 16 } 17 };
33. 搜索旋转排序数组 - 力扣(LeetCode) (leetcode-cn.com)
1 class Solution { 2 public: 3 int search(vector<int>& nums, int target) { 4 int l = 0,r = nums.size()-1; 5 while(l<=r){ 6 int mid = (l+r)/2; 7 if(nums[mid] == target) 8 return mid; 9 if(nums[mid]>=nums[0]){ 10 if(target<=nums[mid]&&target>=nums[0]){ 11 r = mid - 1; 12 }else{ 13 l = mid+1; 14 } 15 }else if(nums[mid]<=nums[nums.size()-1]){ 16 if(target>=nums[mid]&&target<=nums[nums.size()-1]){ 17 l = mid + 1; 18 }else 19 r = mid - 1; 20 } 21 } 22 return -1; 23 } 24 };
5. 最长回文子串 - 力扣(LeetCode) (leetcode-cn.com)
1 class Solution { 2 public: 3 string longestPalindrome(string s) { 4 int left = 0,right = 0,len = 0; 5 vector<vector<int>> dp(s.size(),vector<int>(s.size(),0)); 6 for(int i=0;i<s.size();i++){ 7 for(int j=i;j>=0;j--){//1234,要判断14先做了23的判断 8 if(s[i]==s[j]){ 9 if(i-j<=2) 10 dp[j][i] = 1; 11 else if(dp[j+1][i-1]==1) 12 dp[j][i] = 1; 13 } 14 if(dp[j][i]==1&&i-j+1>len){ 15 len = i-j+1; 16 left = j; 17 right = i; 18 } 19 } 20 } 21 return s.substr(left,len); 22 } 23 };
CodeTop 第二页
200. 岛屿数量 - 力扣(LeetCode) (leetcode-cn.com)
1 class Solution { 2 public: 3 void f(vector<vector<char>>& grid,int x,int y){ 4 if(grid[x][y] == '0') 5 return ; 6 grid[x][y] = '0'; 7 if(y-1 >= 0 && grid[x][y-1] == '1'){ 8 f(grid,x,y-1); 9 } 10 if(y+1 < grid[x].size() && grid[x][y+1] == '1'){ 11 f(grid,x,y+1); 12 } 13 if(x-1 >= 0 && grid[x-1][y] == '1'){ 14 f(grid,x-1,y); 15 } 16 if(x+1 < grid.size() && grid[x+1][y] == '1'){ 17 f(grid,x+1,y); 18 } 19 } 20 int numIslands(vector<vector<char>>& grid) { 21 int ans = 0; 22 for(int i=0;i<grid.size();i++){ 23 for(int j=0;j<grid[i].size();j++){ 24 if(grid[i][j] == '1'){ 25 f(grid,i,j); 26 ans++; 27 } 28 } 29 } 30 return ans; 31 } 32 };
46. 全排列 - 力扣(LeetCode) (leetcode-cn.com)
1 class Solution { 2 public: 3 vector<int> path; 4 vector<vector<int>> result; 5 void f(vector<int>& nums,vector<int>& visit,int sum){ 6 if(sum == nums.size()){ 7 result.push_back(path); 8 return ; 9 } 10 for(int i=0;i<nums.size();i++){ 11 if(visit[i] == 0){ 12 visit[i] = 1; 13 path.push_back(nums[i]); 14 f(nums,visit,sum+1); 15 visit[i] = 0; 16 path.pop_back(); 17 } 18 } 19 } 20 vector<vector<int>> permute(vector<int>& nums) { 21 vector<int>visit(nums.size(),0); 22 f(nums,visit,0); 23 return result; 24 } 25 };
415. 字符串相加 - 力扣(LeetCode) (leetcode-cn.com)
1 class Solution { 2 public: 3 string addStrings(string num1, string num2) {//还有进位哈哈。。还有连续进位9999+1 4 if(num1.size()<num2.size()){ 5 swap(num1,num2); 6 } 7 int n1 = num1.size()-1,n2 = num2.size()-1; 8 while(n2>=0){ 9 num1[n1] = num1[n1]-'0'+num2[n2]; 10 if(num1[n1]>'9'){ 11 num1[n1] -= 10; 12 if(n1-1>=0) 13 num1[n1-1] +=1; 14 else 15 num1 = '1' + num1; 16 } 17 n1--;n2--; 18 } 19 while(n1 >=0 &&num1[n1]>'9'){ 20 num1[n1] -= 10; 21 if(n1-1>=0) 22 num1[n1-1] +=1; 23 else 24 num1 = '1' + num1; 25 n1--;n2--; 26 } 27 return num1; 28 } 29 };
92. 反转链表 II - 力扣(LeetCode) (leetcode-cn.com)
1 class Solution { 2 public: 3 ListNode* reverseBetween(ListNode* head, int left, int right) { 4 if(head==nullptr||head->next==nullptr) 5 return head ; 6 int cnt = right - left + 1; 7 if(left==1){ 8 ListNode *pre = nullptr; 9 ListNode *cur = head; 10 while(cnt--){ 11 ListNode *beh = cur->next; 12 cur->next = pre; 13 pre = cur; 14 cur = beh; 15 } 16 head->next = cur; 17 return pre; 18 } 19 ListNode *head2 = head;//left == 2 20 while(left>2){//left > 2 21 head2 = head2->next; 22 left--; 23 } 24 ListNode *pre = head2; 25 ListNode *cur = head2->next; 26 while(cnt--){ 27 ListNode *beh = cur->next; 28 cur->next = pre; 29 pre = cur; 30 cur = beh; 31 } 32 head2->next->next = cur; 33 head2->next = pre; 34 return head; 35 } 36 };
142. 环形链表 II - 力扣(LeetCode) (leetcode-cn.com)
1 class Solution { 2 public: 3 ListNode *detectCycle(ListNode *head) { 4 if(head==NULL||head->next==NULL) 5 return NULL; 6 ListNode *slow = head->next; 7 ListNode *fast = head->next->next; 8 while(slow!=fast){ 9 if(fast==NULL||fast->next==NULL) 10 return NULL; 11 slow = slow->next; 12 fast = fast->next->next; 13 } 14 while(slow != head){ 15 head = head->next; 16 slow = slow->next; 17 } 18 return head; 19 } 20 };
23. 合并K个升序链表 - 力扣(LeetCode) (leetcode-cn.com)
1 /** 2 * Definition for singly-linked list. 3 * struct ListNode { 4 * int val; 5 * ListNode *next; 6 * ListNode() : val(0), next(nullptr) {} 7 * ListNode(int x) : val(x), next(nullptr) {} 8 * ListNode(int x, ListNode *next) : val(x), next(next) {} 9 * }; 10 */ 11 class Solution { 12 public: 13 ListNode* mergeKLists(vector<ListNode*>& lists) { 14 if(lists.size()==0) 15 return nullptr; 16 for(int i=0;i<lists.size()-1;i++){ 17 ListNode *head = new ListNode(); 18 ListNode *t = head; 19 ListNode *l1 = lists[i]; 20 ListNode *l2 = lists[i+1]; 21 22 while(l1&&l2){ 23 if(l1->val<=l2->val){ 24 t->next = l1; 25 l1 = l1->next; 26 t = t->next; 27 }else{ 28 t->next = l2; 29 l2 = l2->next; 30 t = t->next; 31 } 32 } 33 while(l1){ 34 t->next = l1; 35 l1 = l1->next; 36 t = t->next; 37 } 38 while(l2){ 39 t->next = l2; 40 l2 = l2->next; 41 t = t->next; 42 } 43 lists[i+1] = head->next; 44 } 45 return lists[lists.size()-1]; 46 } 47 };
分治算法更好
54. 螺旋矩阵 - 力扣(LeetCode) (leetcode-cn.com)
1 class Solution { 2 public: 3 vector<int> ans; 4 void f(vector<vector<int>>& matrix,int row,int col,int x,int y){//一行或者一列 5 if(x>row||y>col){ 6 return ; 7 } 8 for(int j=y;j<=col;j++){ 9 ans.push_back(matrix[x][j]); 10 } 11 x++; 12 for(int i = x;i<=row;i++){ 13 ans.push_back(matrix[i][col]); 14 } 15 col--; 16 if(x>row||y>col){ 17 return ; 18 } 19 for(int j = col;j>=y;j--){ 20 ans.push_back(matrix[row][j]); 21 } 22 row--; 23 for(int i = row;i>=x;i--){ 24 ans.push_back(matrix[i][y]); 25 } 26 y++; 27 f(matrix,row,col,x,y); 28 29 } 30 vector<int> spiralOrder(vector<vector<int>>& matrix) { 31 if(matrix.size()==0) 32 return ans; 33 f(matrix,matrix.size()-1,matrix[0].size()-1,0,0); 34 return ans; 35 } 36 };
300. 最长递增子序列 - 力扣(LeetCode) (leetcode-cn.com)
1 class Solution { 2 public: 3 int lengthOfLIS(vector<int>& nums) { 4 int ans = 1; 5 vector<int> dp(nums.size(),1); 6 for(int i=0;i<nums.size();i++){ 7 for(int j=0;j<i;j++){ 8 if(nums[i]>nums[j]){ 9 dp[i] = max(dp[i],dp[j]+1); 10 ans = max(ans,dp[i]); 11 } 12 } 13 } 14 return ans; 15 } 16 };
42. 接雨水 - 力扣(LeetCode) (leetcode-cn.com)
1 class Solution { 2 public: 3 int trap(vector<int>& height) { 4 vector<vector<int>> dp(height.size(),vector<int>(2,0)); 5 dp[0][0] = height[0]; 6 for(int i=1;i<height.size();i++){ 7 dp[i][0] = max(dp[i-1][0],height[i]); 8 } 9 dp[height.size()-1][1] = height[height.size()-1]; 10 for(int i=height.size()-2;i>=0;i--){ 11 dp[i][1] = max(dp[i+1][1],height[i]); 12 } 13 int ans = 0; 14 for(int i=0;i<height.size();i++){ 15 ans += max(min(dp[i][0],dp[i][1])-height[i],0); 16 } 17 return ans; 18 } 19 };
704. 二分查找 - 力扣(LeetCode) (leetcode-cn.com)
1 class Solution { 2 public: 3 int search(vector<int>& nums, int target) { 4 int n = nums.size(); 5 int l = 0,r = n-1; 6 while(l<=r){ 7 int mid = (l+r)/2; 8 if(target == nums[mid]) 9 return mid; 10 if(target < nums[mid]) 11 r = mid - 1; 12 else 13 l = mid + 1; 14 } 15 return -1; 16 } 17 };
94. 二叉树的中序遍历 - 力扣(LeetCode) (leetcode-cn.com)
1 class Solution { 2 public: 3 void f(TreeNode* root,vector<int> &ans){ 4 if(root == nullptr) 5 return ; 6 f(root->left,ans); 7 ans.push_back(root->val); 8 f(root->right,ans); 9 } 10 vector<int> inorderTraversal(TreeNode* root) { 11 vector<int> ans; 12 f(root,ans); 13 return ans; 14 } 15 };
232. 用栈实现队列 - 力扣(LeetCode) (leetcode-cn.com)
1 class MyQueue { 2 public: 3 MyQueue() { 4 5 } 6 stack<int> st1; 7 stack<int> st2; 8 void push(int x) { 9 st1.push(x); 10 } 11 12 int pop() { 13 int x; 14 if(!st2.empty()){ 15 x = st2.top(); 16 st2.pop(); 17 }else{ 18 while(!st1.empty()){ 19 st2.push(st1.top()); 20 st1.pop(); 21 } 22 x = st2.top(); 23 st2.pop(); 24 } 25 return x; 26 } 27 28 int peek() { 29 if(!st2.empty()){ 30 return st2.top(); 31 }else{ 32 while(!st1.empty()){ 33 st2.push(st1.top()); 34 st1.pop(); 35 } 36 } 37 return st2.top(); 38 } 39 40 bool empty() { 41 if(st2.empty()&&st1.empty()) 42 return true; 43 return false; 44 } 45 };
143. 重排链表 - 力扣(LeetCode) (leetcode-cn.com)
1 class Solution { 2 public: 3 void reorderList(ListNode* head) {//先反转后部分然后再插入进前部分 4 if(head==nullptr||head->next==nullptr) 5 return ; 6 ListNode* slow = head; 7 ListNode* fast = head; 8 ListNode* end = nullptr;//end = 2无论奇偶,前部分末尾节点 9 while(fast!=nullptr&&fast->next!=nullptr){ 10 end = slow; 11 slow = slow->next; 12 fast = fast->next->next; 13 } 14 end->next = nullptr; 15 ListNode* pre = nullptr; 16 ListNode* cur = slow; 17 while(cur){ 18 ListNode *t = cur->next; 19 cur->next = pre; 20 pre = cur; 21 cur = t; 22 } 23 ListNode *h = head; 24 while(h!=end){ 25 ListNode *t = pre->next; 26 pre->next = h->next;// 27 h->next = pre; 28 h = h->next->next; 29 pre = t; 30 } 31 h->next = pre; 32 } 33 };
199. 二叉树的右视图 - 力扣(LeetCode) (leetcode-cn.com)
1 class Solution { 2 public: 3 vector<int> ans; 4 void f(TreeNode* root,int depth){ 5 if(root == nullptr) 6 return ; 7 if(depth>=ans.size()) 8 ans.push_back(root->val); 9 f(root->right,depth+1); 10 f(root->left,depth+1); 11 } 12 vector<int> rightSideView(TreeNode* root) { 13 f(root,0); 14 return ans; 15 } 16 };
124. 二叉树中的最大路径和 - 力扣(LeetCode) (leetcode-cn.com)
1 class Solution {//不一定经过根节点,那就对每个节点都看一下是不是最大答案咯 2 public://要维护两个东西,一个是给上层用的root->val,一个是给最终答案 3 //递归,不熟练,两种情况?对于当前节点就两种情况,一种是最终答案,一种给上层用。如果当前节点和右节点都是负数,左节点正数,这种情况的答案在遍历左子树时以左节点为当前节点那会已经做了! 4 int result = -1e8; 5 int maxPathSum(TreeNode* root) { 6 if(root == nullptr) 7 return 0; 8 int left = 0,right = 0; 9 if(root->left){ 10 maxPathSum(root->left); 11 left = max(root->left->val,0); 12 } 13 if(root->right){ 14 maxPathSum(root->right); 15 right = max(root->right->val,0); 16 } 17 result = max(result,left+right+root->val); 18 root->val = max(left,right)+root->val; 19 return result; 20 } 21 };
70. 爬楼梯 - 力扣(LeetCode) (leetcode-cn.com)
1 class Solution { 2 public: 3 int climbStairs(int n) { 4 if(n<=2) 5 return n; 6 vector<int> dp(n); 7 dp[1] = 1;dp[2] = 2; 8 for(int i=3;i<n;i++){ 9 dp[i] = dp[i-1]+dp[i-2]; 10 } 11 return dp[n-1]+dp[n-2]; 12 } 13 };
56. 合并区间 - 力扣(LeetCode) (leetcode-cn.com)
1 class Solution { 2 public: 3 static bool cmp(vector<int>&a,vector<int>&b){ 4 if(a[0]!=b[0]) 5 return a[0]<b[0]; 6 else 7 return a[1]<b[1]; 8 } 9 vector<vector<int>> merge(vector<vector<int>>& intervals) { 10 sort(intervals.begin(),intervals.end(),cmp); 11 vector<vector<int>> result; 12 vector<int> path; 13 for(int i=1;i<intervals.size();i++){//1,4 2,3 14 if(intervals[i-1][1]>=intervals[i][0]){ 15 intervals[i][0] = intervals[i-1][0]; 16 intervals[i][1] = max(intervals[i][1],intervals[i-1][1]); 17 }else{ 18 result.push_back({intervals[i-1][0],intervals[i-1][1]}); 19 } 20 } 21 result.push_back(vector<int>{intervals[intervals.size()-1][0],intervals[intervals.size()-1][1]}); 22 return result; 23 } 24 };
剑指 Offer 22. 链表中倒数第k个节点 - 力扣(LeetCode) (leetcode-cn.com)
1 class Solution { 2 public: 3 ListNode* getKthFromEnd(ListNode* head, int k) { 4 ListNode *ans = head,*tail = head; 5 while(k--){ 6 tail = tail->next; 7 } 8 while(tail){ 9 tail = tail->next; 10 ans = ans->next; 11 } 12 return ans; 13 } 14 };
19. 删除链表的倒数第 N 个结点 - 力扣(LeetCode) (leetcode-cn.com)
1 class Solution { 2 public: 3 ListNode* removeNthFromEnd(ListNode* head, int n) { 4 ListNode *t = head,*del = head,*pre = nullptr; 5 while(n--){ 6 t = t->next; 7 } 8 while(t){ 9 t = t->next; 10 pre = del; 11 del = del->next; 12 } 13 if(pre)//删除头节点pre是空 14 pre->next = del->next; 15 else 16 head = head->next; 17 return head; 18 } 19 };
69. x 的平方根 - 力扣(LeetCode) (leetcode-cn.com)
1 class Solution { 2 public: 3 int mySqrt(int x) {//二分法+用x/i<i而不是i*i>x(溢出) 4 if(x<=1) 5 return x; 6 int l = 0,r = x; 7 while(r-l>=2){//作差为1也就是只有两个数时返回小的那个 8 int mid = (l+r)/2; 9 if(mid == x/mid) 10 return mid; 11 else if(mid > x/mid) 12 r = mid; 13 else 14 l = mid; 15 } 16 return l; 17 } 18 };
CodeTop第三页
8. 字符串转换整数 (atoi) - 力扣(LeetCode) (leetcode-cn.com)
这道题跟x的平方根有相同地方,超过int了,可以用i>x/i这种取巧方法避免越界,我偷懒用longlong了哈哈
1 class Solution { 2 public: 3 int myAtoi(string s) {//2147483647 -2147483648 4 int n = s.size(); 5 long long ans = 0,f = 1; 6 int i = 0; 7 while(i < n&&s[i] == ' ') 8 i++; 9 if(s[i] == '-'){ 10 f = -1; 11 i++; 12 } 13 else if(s[i] == '+'){ 14 i++; 15 } 16 for(;i<n;i++){ 17 if(s[i] >= '0'&&s[i] <= '9'){ 18 ans = ans*10 + s[i] - '0'; 19 if(ans>2147483647&&f == 1){ 20 ans = 2147483647; 21 return ans; 22 } 23 if(ans>2147483648&&f == -1){ 24 ans = -2147483648; 25 return ans; 26 } 27 28 }else 29 break; 30 } 31 ans*=f; 32 return (int)ans; 33 } 34 };
82. 删除排序链表中的重复元素 II - 力扣(LeetCode) (leetcode-cn.com)
1 class Solution { 2 public: 3 ListNode* deleteDuplicates(ListNode* head) { 4 ListNode *cur = head; 5 ListNode *pre = new ListNode(); 6 pre->next = cur; 7 head = pre; 8 while(cur&&cur->next){ 9 if(cur->val == cur->next->val){ 10 while(cur&&cur->next&&cur->val == cur->next->val){ 11 cur = cur->next; 12 } 13 pre->next = cur->next;//pre不动 14 cur = cur->next; 15 } 16 else{ 17 pre = pre->next;//pre移动 18 cur = cur->next; 19 } 20 } 21 return head->next; 22 } 23 };
148. 排序链表 - 力扣(LeetCode) (leetcode-cn.com)
1 class Solution { 2 public: 3 ListNode* merge(ListNode* head){ 4 if(head == nullptr||head->next == nullptr)//保证两个节点 5 return head; 6 ListNode *fast = head->next->next,*slow = head->next; 7 ListNode* pre = head; 8 while(fast!=nullptr&&fast->next!=nullptr){ 9 fast = fast->next->next; 10 pre = slow; 11 slow = slow->next; 12 } 13 pre->next = nullptr; 14 head = merge(head); 15 slow = merge(slow); 16 ListNode *h = new ListNode(); 17 ListNode* ans = h; 18 while(head&&slow){ 19 if(head->val < slow->val){ 20 h->next = head; 21 head = head->next; 22 h = h->next; 23 }else{ 24 h->next = slow; 25 slow = slow->next; 26 h = h->next; 27 } 28 } 29 if(head){ 30 h->next = head; 31 } 32 if(slow){ 33 h->next = slow; 34 } 35 return ans->next; 36 } 37 ListNode* sortList(ListNode* head) { 38 return merge(head); 39 } 40 };
2. 两数相加 - 力扣(LeetCode) (leetcode-cn.com)
链表的题定义假头!
1 class Solution {//插入节点要找到前驱节点 2 public: 3 ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {//假头! 4 ListNode* ans = new ListNode(); 5 ListNode* head = ans; 6 int y = 0; 7 while(l1||l2){ 8 int x1=l1?l1->val:0; 9 int x2 = l2?l2->val:0; 10 y=y+x1+x2; 11 ListNode *t = new ListNode(y%10); 12 head->next = t; 13 head = head->next; 14 l1 = l1?l1->next:nullptr; 15 l2 = l2?l2->next:nullptr; 16 y/=10; 17 } 18 19 if(y==1){ 20 ListNode *t = new ListNode(y); 21 head->next = t; 22 } 23 return ans->next; 24 } 25 };
72. 编辑距离 - 力扣(LeetCode) (leetcode-cn.com)
和链表类似,搞一个空的出来。这道题搞一个空串a和b比,和空串b和a比,这样初始化。然后两层for里,i,j从1开始,if里面word1[i-1]==word2[j-1]
1 class Solution { 2 public: 3 int minDistance(string word1, string word2) { 4 if(word1.size() == 0) 5 return word2.size(); 6 if(word2.size() == 0) 7 return word1.size(); 8 int n1 = word1.size(),n2 = word2.size(); 9 vector<vector<int>> dp(n1+5,vector<int>(n2+5,0)); 10 for(int i=1;i<=n1;i++){//初始化方面拉跨了 11 dp[i][0] = i; 12 } 13 for(int j=1;j<=n2;j++){ 14 dp[0][j] = j; 15 } 16 for(int i = 1;i <= n1;i++){ 17 for(int j = 1;j <= n2;j++){ 18 if(word1[i-1]!=word2[j-1]){ 19 dp[i][j] = min(dp[i-1][j-1],min(dp[i-1][j],dp[i][j-1])) + 1;//1替换,2删除,3增加 20 } 21 else{ 22 dp[i][j] = min(dp[i-1][j-1],min(dp[i-1][j]+1,dp[i][j-1]+1)); 23 } 24 } 25 } 26 return dp[n1][n2]; 27 } 28 };
144. 二叉树的前序遍历 - 力扣(LeetCode) (leetcode-cn.com)
1 class Solution { 2 public: 3 vector<int> ans; 4 vector<int> preorderTraversal(TreeNode* root) { 5 if(root == nullptr) 6 return ans; 7 ans.push_back(root->val); 8 preorderTraversal(root->left); 9 preorderTraversal(root->right); 10 return ans; 11 } 12 };
迭代法(栈实现)
1 class Solution { 2 public: 3 stack<TreeNode*> st; 4 vector<int> preorderTraversal(TreeNode* root) { 5 vector<int> ans; 6 if(root == nullptr) 7 return ans; 8 st.push(root); 9 while(!st.empty()){ 10 TreeNode* t = st.top(); 11 st.pop(); 12 ans.push_back(t->val); 13 if(t->right) 14 st.push(t->right); 15 if(t->left) 16 st.push(t->left); 17 18 } 19 return ans; 20 } 21 };
1143. 最长公共子序列 - 力扣(LeetCode) (leetcode-cn.com)
1 class Solution { 2 public: 3 int longestCommonSubsequence(string text1, string text2) { 4 int ans = 0; 5 int n1 = text1.size(),n2 = text2.size(); 6 vector<vector<int>> dp(n1+1,vector<int>(n2+1,0)); 7 for(int i=1;i<=n1;i++){ 8 for(int j=1;j<=n2;j++){ 9 if(text1[i-1]==text2[j-1]){ 10 dp[i][j] = dp[i-1][j-1]+1; 11 }else{ 12 dp[i][j] = max(dp[i-1][j-1],max(dp[i-1][j],dp[i][j-1])); 13 } 14 ans = max(ans,dp[i][j]); 15 } 16 } 17 return ans; 18 } 19 };
124. 二叉树中的最大路径和 - 力扣(LeetCode) (leetcode-cn.com)
因为这里答案和递归函数返回值不一样,其他人都选择了再声明一个函数,我这边就一个函数了