【代码随想录 】
一、数组
704.二分查找
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Solution {public : int search (vector<int >& nums, int target) { int left = 0 , right = nums.size () - 1 ; int center = 0 ; while (left <= right) { center = (left + right) / 2 ; if (nums[center] == target) return center; if (nums[center] > target) right = center - 1 ; if (nums[center] < target) left = center + 1 ; } return -1 ; } };
时间复杂度:O(log n)
分析:2 x = n → x = l o g 2 n → O ( l o g n ) 2^x = n \to x = log_2n\to O(log\,n) 2 x = n → x = l o g 2 n → O ( l o g n )
空间复杂度:O(1)
27.移除元素
力扣题目链接
1、暴力解法 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Solution {public : int removeElement (vector<int >& nums, int val) { int nowLength = nums.size (); for (int i = 0 ; i < nowLength; i++) { if (nums[i] == val) { for (int j = i; j < nowLength - 1 ; j++) { nums[j] = nums[j + 1 ]; } nowLength--; i--; } } return nowLength; } };
2、快慢指针 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Solution {public : int removeElement (vector<int >& nums, int val) { int len = nums.size (); int slow = 0 ; for (int fast = 0 ; fast < len; fast++) { if (nums[fast] != val) { nums[slow++] = nums[fast]; } } return slow; } };
977.有序数组的平方
力扣题目链接
1、平方后排序
1 2 3 4 5 6 7 8 9 10 11 12 class Solution {public : vector<int > sortedSquares (vector<int >& nums) { int len = nums.size (); for (int i = 0 ; i < len; i++) { nums[i] = nums[i] * nums[i]; } sort (nums.begin (),nums.end ()); return nums; } };
时间复杂度:O(nlogn)
2、双指针
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class Solution {public : vector<int > sortedSquares (vector<int >& nums) { int len = nums.size (); vector<int > ans (len, 0 ) ; int cnt = len; int i = 0 , j = len - 1 ; while (i <= j) { if (nums[i] * nums[i] > nums[j] * nums[j]) { ans[--cnt] = nums[i] * nums[i]; i++; } else { ans[--cnt] = nums[j] * nums[j]; j--; } } return ans; } };
209.长度最小的子数组
力扣题目链接
快慢指针 (滑动窗口)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Solution {public : int minSubArrayLen (int target, vector<int >& nums) { int len = nums.size (); int fast = 0 , slow = 0 ; int sum = 0 ; int ans = 0x7fffffff ; for (; fast <= len; fast++) { if (fast < len && sum < target) { sum += nums[fast]; continue ; } if (sum >= target) { ans = (fast - slow) < ans ? (fast - slow) : ans; sum -= nums[slow++]; fast--; } } if (ans < 0x7fffffff ) return ans; else return 0 ; } };
59.螺旋矩阵II
力扣题目链接
1、一个一个看,走满就换方向
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 class Solution {public : enum Direction {RIGHT, DOWN, LEFT, UP}d; bool isOver (int x, int y, int maxX, int maxY) { if (x < 0 || y < 0 || x >= maxX || y >= maxY) return true ; return false ; } Direction changeDirection (Direction d) { switch (d) { case RIGHT: d = DOWN; break ; case DOWN: d = LEFT; break ; case LEFT: d = UP; break ; case UP: d = RIGHT;break ; } return d; } vector<vector<int >> generateMatrix (int n) { vector<vector<int > > ans (n, vector <int >(n, 0 )); d = RIGHT; int x = 0 , y = 0 ; for (int i = 1 ; i <= n * n; i++) { switch (d) { case RIGHT: if (!isOver (x, y, n, n) && ans[x][y] == 0 ) { ans[x][y] = i; y++; } else { d = changeDirection (d); i--; y--; x++; } break ; case DOWN: if (!isOver (x, y, n, n) && ans[x][y] == 0 ) { ans[x][y] = i; x++; } else { d = changeDirection (d); i--; x--; y--; } break ; case LEFT: if (!isOver (x, y, n, n) && ans[x][y] == 0 ) { ans[x][y] = i; y--; } else { d = changeDirection (d); i--; y++; x--; } break ; case UP: if (!isOver (x, y, n, n) && ans[x][y] == 0 ) { ans[x][y] = i; x--; } else { d = changeDirection (d); i--; x++; y++; } break ; } } return ans; } };
2、分圈,一圈看四条边【代码随想录】
二、链表
203.移除链表元素
力扣题目链接
增加哨兵节点 (养成删除内存的习惯)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 class Solution {public : ListNode* removeElements (ListNode* head, int val) { if (!head) return nullptr ; ListNode* head0 = new ListNode; head0->next = head; ListNode* tmp = head0; while (tmp) { if (tmp->next && tmp->next->val == val) { tmp->next = tmp->next->next; continue ; } tmp = tmp->next; } return head0->next; } };
707.设计链表
力扣题目链接
遇到tmp->next,还是判一下tmp吧
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 class MyLinkedList {public : struct ListNode { int val; ListNode *next; ListNode () : val (0 ), next (nullptr ) {} ListNode (int x) : val (x), next (nullptr ) {} ListNode (int x, ListNode *next) : val (x), next (next) {} } *head; MyLinkedList () { head = new ListNode; } int get (int index) { ListNode *tmp = head->next; while (index--) { if (!tmp) return -1 ; tmp = tmp->next; } if (!tmp) return -1 ; return tmp->val; } void addAtHead (int val) { ListNode *newNode = new ListNode (val); newNode->next = head->next; head->next = newNode; } void addAtTail (int val) { ListNode *newNode = new ListNode (val); ListNode *tmp = head; while (tmp->next) tmp = tmp->next; tmp->next = newNode; } void addAtIndex (int index, int val) { ListNode *newNode = new ListNode (val); ListNode *tmp = head; while (index-- && tmp) tmp = tmp->next; if (index > 0 || !tmp) return ; newNode->next = tmp->next; tmp->next = newNode; } void deleteAtIndex (int index) { ListNode *tmp = head; while (index-- && tmp) tmp = tmp->next; if (index > 0 || !tmp || !tmp->next) return ; ListNode *need2Delete = tmp->next; tmp->next = tmp->next->next; delete need2Delete; } };
206.反转链表
力扣题目链接
1、双指针法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 class Solution {public : ListNode* reverseList (ListNode* head) { if (!head || !head->next) return head; ListNode *slow = head; ListNode *fast = head->next; ListNode *tmp = nullptr ; slow->next = nullptr ; while (fast) { tmp = fast->next; fast->next = slow; slow = fast; fast = tmp; } return slow; } };
2、递归法
24.两两交换链表中的节点
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 class Solution {public : ListNode* swapPairs (ListNode* head) { if (!head || !head->next) return head; ListNode *head0 = new ListNode (0 , head); ListNode *pre = head0; ListNode *key1 = head, *key2 = head->next; while (1 ) { pre->next = key2; key1->next = key2->next; key2->next = key1; pre = key1; key1 = key1->next; if (!key1) return head0->next; key2 = key1->next; if (!key2) return head0->next; } } };
19.删除链表的倒数第N个节点
力扣题目链接
1、循环两次
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 class Solution {public : int count (ListNode* head) { int cnt = 0 ; while (head) { cnt++; head = head->next; } return cnt; } ListNode* removeNthFromEnd (ListNode* head, int n) { n = count (head) - n + 1 ; if (!head->next) { delete head; return nullptr ; } ListNode *head0 = new ListNode (0 , head); ListNode *fast = head0, *slow = nullptr ; while (n--) { slow = fast; fast = fast->next; } slow->next = fast->next; delete fast; return head0->next; } };
2、双指针【进阶】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 class Solution {public : ListNode* removeNthFromEnd (ListNode* head, int n) { ListNode *head0 = new ListNode (0 , head); ListNode *fast = head0, *slow = head0; while (n--) fast = fast->next; while (fast->next) { fast = fast->next; slow = slow->next; } ListNode *need2Delete = slow->next; slow->next = slow->next->next; delete need2Delete; return head0->next; } };
面试题 02.07. 链表相交
力扣题目链接
同:160. 相交链表 - 力扣(Leetcode)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 class Solution {public : int count (ListNode *head) { int cnt = 0 ; while (head) { cnt++; head = head->next; } return cnt; } ListNode *findAnsNode (int nA, int nB, ListNode *headA, ListNode *headB) { for (int i = 0 ; i < nA - nB; i++) headA = headA->next; if (headA == headB) return headA; while (nB--) { if (!headA->next || !headB->next) return nullptr ; if (headA->next == headB->next) return headA->next; headA = headA->next; headB = headB->next; } return nullptr ; } ListNode *getIntersectionNode (ListNode *headA, ListNode *headB) { int nA = count (headA), nB = count (headB); if (nA >= nB) return findAnsNode (nA, nB, headA, headB); else return findAnsNode (nB, nA, headB, headA); } };
时间复杂度:O(n + m)
空间复杂度:O(1)
142.环形链表II
力扣题目链接
找到相遇点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 class Solution {public : ListNode *detectCycle (ListNode *head) { ListNode *slow = head, *fast = head; while (fast && fast->next) { slow = slow->next; fast = fast->next->next; if (slow == fast) { slow = head; while (slow != fast) { slow = slow->next; fast = fast->next; } return slow; } } return nullptr ; } };
三、哈希表
242.有效的字母异位词
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Solution {public : bool isAnagram (string s, string t) { vector<int > charSet (26 , 0 ) ; int ns = s.size (), nt = t.size (); for (int i = 0 ; i < ns; i++) { charSet[s[i] - 'a' ]++; } for (int i = 0 ; i < nt; i++) { charSet[t[i] - 'a' ]--; } for (int i = 0 ; i < 26 ; i++) { if (charSet[i] != 0 ) return false ; } return true ; } };
349.两个数组的交集
力扣题目链接
1、哈希表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Solution {public : vector<int > intersection (vector<int >& nums1, vector<int >& nums2) { unordered_set<int > ans; unordered_set<int > nums1_set (nums1.begin(), nums1.end()) ; for (int item : nums2) { if (nums1_set.find (item) != nums1_set.end ()) { ans.insert (item); } } return vector <int >(ans.begin (), ans.end ()); } };
2、数组做哈希表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Solution {public : vector<int > intersection (vector<int >& nums1, vector<int >& nums2) { unordered_set<int > ans; int record[1000 ] = {0 }; int n1 = nums1.size (), n2 = nums2.size (); for (int i = 0 ; i < n1; i++) { record[nums1[i]] = 1 ; } for (int i = 0 ; i < n2; i++) { if (record[nums2[i]]) ans.insert (nums2[i]); } return vector <int >(ans.begin (), ans.end ());; } };
202.快乐数
力扣题目链接
1、快慢指针 + 递归
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class Solution {public : int getSum (int n) { int sum = 0 ; while (n) { sum += (n % 10 ) * (n % 10 ); n /= 10 ; } return sum; } bool judge (int fast, int slow) { fast = getSum (getSum (fast)); slow = getSum (slow); if (fast == 1 ) return true ; if (fast == slow) return false ; return judge (fast, slow); } bool isHappy (int n) { return judge (n, n); } };
2、哈希表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 class Solution {public : int getSum (int n) { int sum = 0 ; while (n) { sum += (n % 10 ) * (n % 10 ); n /= 10 ; } return sum; } bool judge (int n, unordered_set<int >& cnt) { if (n == 1 ) return true ; if (cnt.find (n) != cnt.end ()) { return false ; } else { cnt.insert (n); } n = getSum (n); return judge (n, cnt); } bool isHappy (int n) { unordered_set<int > cnt; return judge (n, cnt); } };
1.两数之和
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Solution {public : vector<int > twoSum (vector<int >& nums, int target) { unordered_map<int , int > record; int n = nums.size (); for (int i = 0 ; i < n; i++) { if (record.find (target - nums[i]) != record.end ()) { return {i, record.find (target - nums[i])->second}; } record.insert (pair <int , int >(nums[i], i)); } return {}; } };
454.四数相加II
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Solution {public : int fourSumCount (vector<int >& nums1, vector<int >& nums2, vector<int >& nums3, vector<int >& nums4) { int ans = 0 ; int n1 = nums1.size (), n2 = nums2.size (), n3 = nums3.size (), n4 = nums4.size (); unordered_map<int , int > map; for (int i : nums1) { for (int j : nums2) { map[i + j]++; } } for (int k : nums3) { for (int l : nums4) { if (map.find (0 - k - l) != map.end ()) { ans += map[0 - k - l]; } } } return ans; } };
383.赎金信
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Solution {public : bool canConstruct (string ransomNote, string magazine) { vector<int > mCnt (26 , 0 ) ; for (char i : magazine) mCnt[i - 'a' ]++; for (char i : ransomNote) { mCnt[i - 'a' ]--; if (mCnt[i - 'a' ] < 0 ) return false ; } return true ; } };
15.三数之和
力扣题目链接
18.四数之和
力扣题目链接
四、字符串
344.反转字符串
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 class Solution {public : void reverseString (vector<char >& s) { int left = 0 , right = s.size () - 1 ; while (left < right) { char tmp = s[left]; s[left] = s[right]; s[right] = tmp; left++; right--; } } };
541.反转字符串II
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 class Solution {public : void reverseString (string& s, int left, int right) { while (left < right) { char tmp = s[left]; s[left] = s[right]; s[right] = tmp; left++; right--; } } string reverseStr (string s, int k) { int n = s.size (); int begin = 0 ; for (int i = 0 ; i < n; i += 2 * k) { int left = n - i; if (left < k) { reverseString (s, begin, n - 1 ); break ; } else if (left < 2 * k) { reverseString (s, begin, begin + k - 1 ); break ; } reverseString (s, begin, begin + k - 1 ); begin += 2 * k; } return s; } };
剑指Offer 05.替换空格
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Solution {public : string replaceSpace (string s) { int oldSize = s.size (); int cnt = 0 ; for (int i = 0 ; i < oldSize; i++) { if (s[i] == ' ' ) cnt++; } s.resize (oldSize + cnt *2 ); int newSize = s.size (); int slow = oldSize - 1 , fast = newSize - 1 ; while (slow < fast) { if (s[slow] == ' ' ) { s[fast--] = '0' ; s[fast--] = '2' ; s[fast--] = '%' ; slow--; } else s[fast--] = s[slow--]; } return s; } };
151.翻转字符串里的单词
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 class Solution {public : void reverseString (string& s, int left, int right) { while (left < right) { char tmp = s[left]; s[left] = s[right]; s[right] = tmp; left++; right--; } } void processSpaces (string& s) { int slow = 0 ; int n = s.size (); int flag = 0 ; for (int fast = 0 ; fast < n; fast++) { if (s[fast] != ' ' ) { flag = 1 ; s[slow++] = s[fast]; } else { if (flag) s[slow++] = ' ' ; flag = 0 ; } } if (s[slow - 1 ] == ' ' ) s.resize (slow - 1 ); else s.resize (slow); } string reverseWords (string s) { processSpaces (s); reverseString (s, 0 , s.size () - 1 ); int begin = 0 , end = 0 ; int n = s.size (); while (end < n) { if (s[end] == ' ' ) { reverseString (s, begin, end - 1 ); begin = end + 1 ; } end++; } reverseString (s, begin, end - 1 ); return s; } };
剑指Offer58-II.左旋转字符串
力扣题目链接
不开辟新的空间
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Solution {public : void reverseString (string& s, int left, int right) { while (left < right) { char tmp = s[left]; s[left] = s[right]; s[right] = tmp; left++; right--; } } string reverseLeftWords (string s, int n) { reverseString (s, 0 , n - 1 ); reverseString (s, n, s.size () - 1 ); reverseString (s, 0 , s.size () - 1 ); return s; } };
28.实现 strStr()
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 class Solution {public : vector<int > getNext (string s) { int n = s.size (); vector<int > next (n, 0 ) ; int j = -1 ; next[0 ] = j; for (int i = 1 ; i < n; i++) { while (j >= 0 && s[j + 1 ] != s[i]) { j = next[j]; } if (s[j + 1 ] == s[i]) j++; next[i] = j; } return next; } int strStr (string haystack, string needle) { if (needle.size () == 0 ) return 0 ; vector<int > next = getNext (needle); int n = haystack.size (), m = needle.size (); int j = -1 ; for (int i = 0 ; i < n; i++) { while (j >= 0 && needle[j + 1 ] != haystack[i]) { j = next[j]; } if (needle[j + 1 ] == haystack[i]) j++; if (j + 1 == m) { return i - needle.size () + 1 ; } } return -1 ; } };
459.重复的子字符串
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 class Solution {public : vector<int > getNext (string s) { int n = s.size (); vector<int > next (n, 0 ) ; int j = -1 ; next[0 ] = j; for (int i = 1 ; i < n; i++) { while (j >= 0 && s[j + 1 ] != s[i]) { j = next[j]; } if (s[j + 1 ] == s[i]) j++; next[i] = j; } return next; } bool repeatedSubstringPattern (string s) { if (s.size () == 0 ) return false ; vector<int > next = getNext (s); if (next[next.size () - 1 ] != -1 && s.size () % (next.size () - next[next.size () - 1 ] - 1 ) == 0 ) return true ; return false ; } };
五、双指针法(同上)
27.移除元素
力扣题目链接
344.反转字符串
力扣题目链接
剑指Offer 05.替换空格
力扣题目链接
151.翻转字符串里的单词
力扣题目链接
206.反转链表
力扣题目链接
24. 两两交换链表中的节点
力扣题目链接
19.删除链表的倒数第N个节点
力扣题目链接
面试题 02.07. 链表相交
力扣题目链接
同:160. 相交链表 - 力扣(Leetcode)
142.环形链表II
力扣题目链接
15.三数之和
力扣题目链接
18.四数之和
力扣题目链接
六、栈与队列
232.用栈实现队列
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 class MyQueue {public : stack<int > stackIn; stack<int > stackOut; MyQueue () { } void push (int x) { stackIn.push (x); } int pop () { if (stackOut.empty ()) { while (!stackIn.empty ()) { stackOut.push (stackIn.top ()); stackIn.pop (); } } if (stackOut.empty ()) { printf ("当前没有元素\n" ); return -1 ; } int res = stackOut.top (); stackOut.pop (); return res; } int peek () { int res = this ->pop (); stackOut.push (res); return res; } bool empty () { if (stackOut.empty () && stackIn.empty ()) return true ; return false ; } };
225.用队列实现栈
力扣题目链接
1、两个队列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 class MyStack {public : queue<int > q1; queue<int > q2; MyStack () {} void push (int x) { q1.push (x); } int pop () { if (this ->empty ()) printf ("当前没有元素\n" ); int size = q1.size () - 1 ; while (size--) { q2.push (q1.front ()); q1.pop (); } int res = q1.front (); q1.pop (); if (q1.empty ()) swap (q1, q2); return res; } int top () { int res = this ->pop (); q1.push (res); return res; } bool empty () { if (q1.empty () && q2.empty ()) return true ; return false ; } };
2、一个队列(优化)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 class MyStack {public : queue<int > q; MyStack () { } void push (int x) { q.push (x); } int pop () { int res = q.back (); int t = q.size () - 1 ; while (t--) { q.push (q.front ()); q.pop (); } q.pop (); return res; } int top () { int res = this ->pop (); q.push (res); return res; } bool empty () { if (q.empty ()) return true ; return false ; } };
20.有效的括号
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class Solution {public : bool isValid (string s) { stack<char > st; int n = s.size (); for (int i = 0 ; i < n; i++ ) { if (s[i] == '(' ) st.push (')' ); else if (s[i] == '[' ) st.push (']' ); else if (s[i] == '{' ) st.push ('}' ); else { if (st.empty ()) return false ; else if (st.top () == s[i]) st.pop (); else return false ; } } return st.empty (); } };
1047.删除字符串中的所有相邻重复项
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Solution {public : string removeDuplicates (string s) { int slow = 0 ; for (int i = 0 ; i < s.size (); i++) { if (slow == 0 ) { s[slow++] = s[i]; } else if (s[slow - 1 ] != s[i]) { s[slow++] = s[i]; } else { slow--; } } s.resize (slow); return s; } };
150.逆波兰表达式求值
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 class Solution {public : int str2int (const string str) { int res = 0 ; int flag = 0 ; for (char i : str) { if (i == '-' ) { flag = 1 ; continue ; } res = res * 10 + i - '0' ; } return flag ? 0 - res : res; } int evalRPN (vector<string>& tokens) { stack<long long > st; for (string i : tokens) { if (i[0 ] >= '0' && i[0 ] <= '9' || i[0 ] == '-' && i.size () > 1 ) { st.push (str2int (i)); printf ("%d压入栈\n" , str2int (i)); } else { int tmp = 0 ; int key2 = st.top (); st.pop (); int key1 = st.top (); st.pop (); if (i[0 ] == '+' ) { tmp = key1 + key2; } else if (i[0 ] == '-' ) { tmp = key1 - key2; } else if (i[0 ] == '*' ) { tmp = key1 * key2; } else if (i[0 ] == '/' ) { tmp = key1 / key2; } st.push (tmp); printf ("%d %c %d = %d\n" , key1, i[0 ], key2, tmp); } } return st.top (); } };
七、二叉树
递归遍历/迭代遍历
144.二叉树的前序遍历
力扣题目链接
1、递归遍历
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Solution {public : void traverse (TreeNode *node, vector<int >& ans) { if (node == nullptr ) return ; ans.push_back (node->val); traverse (node->left, ans); traverse (node->right, ans); return ; } vector<int > preorderTraversal (TreeNode* root) { vector<int > ans; traverse (root, ans); return ans; } };
2、迭代遍历
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 class Solution {public : vector<int > preorderTraversal (TreeNode* root) { vector<int > ans; stack<TreeNode *> st; st.push (root); while (!st.empty ()) { TreeNode *tmp = st.top (); st.pop (); if (tmp == nullptr ) continue ; ans.push_back (tmp->val); st.push (tmp->right); st.push (tmp->left); } return ans; } };
145.二叉树的后序遍历
力扣题目链接
1、递归遍历
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Solution {public : void traverse (TreeNode *node, vector<int >& ans) { if (node == nullptr ) return ; traverse (node->left, ans); traverse (node->right, ans); ans.push_back (node->val); return ; } vector<int > postorderTraversal (TreeNode* root) { vector<int > ans; traverse (root, ans); return ans; } };
2、迭代遍历
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 class Solution {public : vector<int > postorderTraversal (TreeNode* root) { vector<int > ans; stack<TreeNode *> st; st.push (root); while (!st.empty ()) { TreeNode *tmp = st.top (); st.pop (); if (tmp == nullptr ) continue ; ans.push_back (tmp->val); st.push (tmp->left); st.push (tmp->right); } reverse (ans.begin (), ans.end ()); return ans; } };
94.二叉树的中序遍历
力扣题目链接
1、递归遍历
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Solution {public : void traverse (TreeNode *node, vector<int >& ans) { if (node == nullptr ) return ; traverse (node->left, ans); ans.push_back (node->val); traverse (node->right, ans); return ; } vector<int > inorderTraversal (TreeNode* root) { vector<int > ans; traverse (root, ans); return ans; } };
2、迭代遍历
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 class Solution {public : vector<int > inorderTraversal (TreeNode* root) { vector<int > ans; stack<TreeNode *> st; while (root || !st.empty ()) { if (root != nullptr ) { st.push (root); root = root->left; } else { root = st.top (); ans.push_back (root->val); st.pop (); root = root->right; } } return ans; } };
589.N 叉树的前序遍历
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 class Solution {public : vector<int > ans; vector<int > preorder (Node* root) { if (root == nullptr ) return ans; ans.push_back (root->val); for (int i = 0 ; i < root->children.size (); i++) preorder (root->children[i]); return ans; } };
590.N 叉树的后序遍历
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 class Solution {public : vector<int > ans; vector<int > postorder (Node* root) { if (root == nullptr ) return ans; for (int i = 0 ; i < root->children.size (); i++) preorder (root->children[i]); ans.push_back (root->val); return ans; } };
层序遍历
102.二叉树的层序遍历
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 class Solution {public : vector<vector<int >> levelOrder (TreeNode* root) { vector<vector<int >> ans; if (!root) return ans; queue<TreeNode *> que; que.push (root); while (!que.empty ()) { int curSize = que.size (); vector<int > curAns; for (int i = 0 ; i < curSize; i++) { TreeNode *tmp = que.front (); curAns.push_back (tmp->val); que.pop (); if (tmp->left) que.push (tmp->left); if (tmp->right) que.push (tmp->right); } ans.push_back (curAns); } return ans; } };
107.二叉树的层序遍历 II
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 class Solution {public : vector<vector<int >> levelOrderBottom (TreeNode* root) { vector<vector<int >> ans; if (!root) return ans; queue<TreeNode *> que; que.push (root); while (!que.empty ()) { int curSize = que.size (); vector<int > curAns; for (int i = 0 ; i < curSize; i++) { TreeNode *tmp = que.front (); curAns.push_back (tmp->val); que.pop (); if (tmp->left) que.push (tmp->left); if (tmp->right) que.push (tmp->right); } ans.push_back (curAns); } reverse (ans.begin (), ans.end ()); return ans; } };
199. 二叉树的右视图
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 class Solution {public : vector<int > rightSideView (TreeNode* root) { vector<int > ans; if (root == nullptr ) return ans; queue<TreeNode *> que; que.push (root); while (!que.empty ()) { int n = que.size () - 1 ; while (n--) { if (que.front ()->left) que.push (que.front ()->left); if (que.front ()->right) que.push (que.front ()->right); que.pop (); } if (que.front ()->left) que.push (que.front ()->left); if (que.front ()->right) que.push (que.front ()->right); ans.push_back (que.front ()->val); que.pop (); } return ans; } };
637.二叉树的层平均值
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 class Solution {public : vector<double > averageOfLevels (TreeNode* root) { vector<double > ans; if (!root) return ans; queue<TreeNode *> que; que.push (root); while (!que.empty ()) { double curSum = 0 ; int size = que.size (); for (int i = 0 ; i < size; i++) { curSum += que.front ()->val; if (que.front ()->left) que.push (que.front ()->left); if (que.front ()->right) que.push (que.front ()->right); que.pop (); } ans.push_back (curSum / size); } return ans; } };
429.N叉树的层序遍历
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 class Solution {public : vector<vector<int >> levelOrder (Node* root) { vector<vector<int >> ans; if (!root) return ans; queue<Node *> que; que.push (root); while (!que.empty ()) { int curSize = que.size (); vector<int > curAns; for (int i = 0 ; i < curSize; i++) { Node *tmp = que.front (); curAns.push_back (tmp->val); que.pop (); for (Node* j : tmp->children) if (j) que.push (j); } ans.push_back (curAns); } return ans; } };
515.在每个树行中找最大值
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 class Solution {public : vector<int > largestValues (TreeNode* root) { vector<int > ans; if (!root) return ans; queue<TreeNode *> que; que.push (root); while (!que.empty ()) { int curMax = INT_MIN; int size = que.size (); for (int i = 0 ; i < size; i++) { curMax = curMax < que.front ()->val ? que.front ()->val : curMax; if (que.front ()->left) que.push (que.front ()->left); if (que.front ()->right) que.push (que.front ()->right); que.pop (); } ans.push_back (curMax); } return ans; } };
116.填充每个节点的下一个右侧节点指针
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 class Solution {public : Node* connect (Node* root) { if (!root) return root; queue<Node *> que; que.push (root); while (!que.empty ()) { int curSize = que.size (); for (int i = 0 ; i < curSize; i++) { Node *tmp = que.front (); que.pop (); if (i == curSize - 1 ) tmp->next = nullptr ; else tmp->next = que.front (); if (tmp->left) que.push (tmp->left); if (tmp->right) que.push (tmp->right); } } return root; } };
117.填充每个节点的下一个右侧节点指针II
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 class Solution {public : Node* connect (Node* root) { if (!root) return root; queue<Node *> que; que.push (root); while (!que.empty ()) { int curSize = que.size (); for (int i = 0 ; i < curSize; i++) { Node *tmp = que.front (); que.pop (); if (i == curSize - 1 ) tmp->next = nullptr ; else tmp->next = que.front (); if (tmp->left) que.push (tmp->left); if (tmp->right) que.push (tmp->right); } } return root; } };
104.二叉树的最大深度
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 class Solution {public : int maxDepth (TreeNode* root) { int ans = 0 ; if (!root) return ans; queue<TreeNode *> que; que.push (root); while (!que.empty ()) { ans++; int curSize = que.size (); for (int i = 0 ; i < curSize; i++) { if (que.front ()->left) que.push (que.front ()->left); if (que.front ()->right) que.push (que.front ()->right); que.pop (); } } return ans; } };
111.二叉树的最小深度
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 class Solution {public : int minDepth (TreeNode* root) { int ans = 0 ; if (!root) return ans; queue<TreeNode *> que; que.push (root); while (!que.empty ()) { int curSize = que.size (); ans++; for (int i = 0 ; i < curSize; i++) { if (!que.front ()->left && !que.front ()->right) return ans; if (que.front ()->left) que.push (que.front ()->left); if (que.front ()->right) que.push (que.front ()->right); que.pop (); } } return ans; } };
226.翻转二叉树
力扣题目链接
1、递归法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Solution {public : TreeNode* invertTree (TreeNode* root) { if (root == nullptr ) return root; swap (root->left, root->right); invertTree (root->left); invertTree (root->right); return root; } };
2、迭代法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class Solution {public : TreeNode* invertTree (TreeNode* root) { if (root == nullptr ) return root; stack<TreeNode*> st; st.push (root); while (!st.empty ()) { TreeNode *tmp = st.top (); swap (tmp->left, tmp->right); st.pop (); if (tmp->right) st.push (tmp->right); if (tmp->left) st.push (tmp->left); } return root; } };
100.相同的树
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Solution {public : bool isSameTree (TreeNode* p, TreeNode* q) { if (!p && !q) return true ; if (p && !q || !p && q) return false ; if (p->val == q->val && isSameTree (p->left, q->left) && isSameTree (p->right, q->right)) return true ; return false ; } };
101.对称二叉树
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 class Solution {public : bool preOrdertraverse (TreeNode *t1, TreeNode *t2) { if (!t1 && !t2) return true ; if (t1 && !t2 || !t1 && t2) return false ; if (t1->val == t2->val && preOrdertraverse (t1->left, t2->right) && preOrdertraverse (t1->right, t2->left)) return true ; return false ; } bool isSymmetric (TreeNode* root) { if (!root) return true ; return preOrdertraverse (root->left, root->right); } };
572.另一棵树的子树
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 class Solution {public : bool isSameTree (TreeNode* p, TreeNode* q) { if (!p && !q) return true ; if (p && !q || !p && q) return false ; if (p->val == q->val && isSameTree (p->left, q->left) && isSameTree (p->right, q->right)) return true ; return false ; } bool isSubtree (TreeNode* root, TreeNode* subRoot) { if (!root) return false ; return isSameTree (root, subRoot) || isSubtree (root->left, subRoot) || isSubtree (root->right, subRoot); } };
559.n叉树的最大深度
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 class Solution {public : int maxDepth (Node* root) { int ans = 0 ; if (!root) return ans; queue<Node *> que; que.push (root); while (!que.empty ()) { ans++; int curSize = que.size (); for (int i = 0 ; i < curSize; i++) { for (Node* j : que.front ()->children) if (j) que.push (j); que.pop (); } } return ans; } };
222.完全二叉树的节点个数
力扣题目链接
1、当做普通二叉树遍历
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 class Solution {public : int countNodes (TreeNode* root) { int ans = 0 ; if (!root) return ans; stack<TreeNode*> st; st.push (root); while (!st.empty ()) { ans++; TreeNode *tmp = st.top (); st.pop (); if (tmp->right) st.push (tmp->right); if (tmp->left) st.push (tmp->left); } return ans; } };
2、完全二叉树
完全二叉树只有两种情况,情况一:就是满二叉树,情况二:最后一层叶子节点没有满。
对于情况一,可以直接用 2^树深度 - 1 来计算,注意这里根节点深度为1。
对于情况二,分别递归左孩子,和右孩子,递归到某一深度一定会有左孩子或者右孩子为满二叉树,然后依然可以按照情况1来计算。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 class Solution {public : int countNodes (TreeNode* root) { if (!root) return 0 ; TreeNode *left = root->left; TreeNode *right = root->right; int lenLeft = 0 , lenRight = 0 ; while (left) { lenLeft++; left = left->left; } while (left) { lenRight++; right = right->right; } if (lenLeft == lenRight) return (2 << lenLeft) - 1 ; return 1 + countNodes (root->left) + countNodes (root->right); } };
时间复杂度:O(log n × log n)
空间复杂度:O(log n)
110.平衡二叉树
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Solution {public : int postOrderTravese (TreeNode *t, int depth) { if (!t) return depth - 1 ; int lenLeft = postOrderTravese (t->left, depth + 1 ); int lenRight = postOrderTravese (t->right, depth + 1 ); return abs (lenLeft - lenRight) > 1 ? -1 : max (lenLeft, lenRight); } bool isBalanced (TreeNode* root) { if (!root) return true ; if (postOrderTravese (root, 1 ) == -1 ) return false ; return true ; } };
257. 二叉树的所有路径
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 class Solution {public : void postOrderTraverse (TreeNode *t, string s, vector<string>& ans) { if (!t->left && !t->right) ans.push_back (s); else { if (t->left) postOrderTraverse (t->left, s + "->" + to_string (t->left->val), ans); if (t->right) postOrderTraverse (t->right, s + "->" + to_string (t->right->val), ans); } return ; } vector<string> binaryTreePaths (TreeNode* root) { vector<string> ans; if (!root) return ans; postOrderTraverse (root, to_string (root->val), ans); return ans; } };
404.左叶子之和
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 class Solution {public : int sumOfLeftLeaves (TreeNode* root) { if (!root) return 0 ; int ans = 0 ; queue<TreeNode *> que; que.push (root); while (!que.empty ()) { int size = que.size (); while (size--) { if (que.front ()->left) { que.push (que.front ()->left); if (!que.front ()->left->left && !que.front ()->left->right) ans += que.front ()->left->val; } if (que.front ()->right) que.push (que.front ()->right); que.pop (); } } return ans; } };
513.找树左下角的值
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 class Solution {public : int findBottomLeftValue (TreeNode* root) { if (!root) return 0 ; int ans = 0 ; queue<TreeNode *> que; que.push (root); while (!que.empty ()) { int size = que.size (); ans = que.front ()->val; while (size--) { if (que.front ()->left) que.push (que.front ()->left); if (que.front ()->right) que.push (que.front ()->right); que.pop (); } } return ans; } };
112.路径总和
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Solution {public : bool traverse (TreeNode *t, int targetSum, int curSum) { if (!t) return false ; curSum += t->val; if (curSum == targetSum && !t->left && !t->right) return true ; return traverse (t->left, targetSum, curSum) || traverse (t->right, targetSum, curSum); } bool hasPathSum (TreeNode* root, int targetSum) { return traverse (root, targetSum, 0 ); } };
106.从中序与后序遍历序列构造二叉树
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 class Solution {public : int findRoot (vector<int >& inorder, int key, int inbegin, int inend) { for (int i = inbegin; i <= inend; i++) { if (inorder[i] == key) return i; } return -1 ; } TreeNode* preOrder (vector<int >& inorder, int inbegin, int inend, vector<int >& postorder, int postbegin, int postend) { if (inbegin > inend) return nullptr ; int inRoot = findRoot (inorder, postorder[postend], inbegin, inend); return new TreeNode (postorder[postend], preOrder (inorder, inbegin, inRoot - 1 , postorder, postbegin, postbegin + (inRoot - 1 - inbegin)), preOrder (inorder, inRoot + 1 , inend, postorder, postend - 1 - (inend - inRoot - 1 ) ,postend - 1 )); } TreeNode* buildTree (vector<int >& inorder, vector<int >& postorder) { return preOrder (inorder, 0 , inorder.size () - 1 , postorder, 0 , postorder.size () - 1 ); } };
654.最大二叉树
力扣题目地址
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 class Solution {public : int findRoot (vector<int >& nums, int begin, int end) { int maxVal = INT_MIN, index = -1 ; for (int i = begin; i <= end; i++) if (maxVal < nums[i]) { maxVal = nums[i]; index = i; } return index; } TreeNode* construct (vector<int >& nums, int begin, int end) { if (begin > end) return nullptr ; int indexRoot = findRoot (nums, begin, end); return new TreeNode (nums[indexRoot], construct (nums, begin, indexRoot - 1 ), construct (nums, indexRoot + 1 , end)); } TreeNode* constructMaximumBinaryTree (vector<int >& nums) { return construct (nums, 0 , nums.size () - 1 ); } };
617.合并二叉树
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Solution {public : TreeNode* mergeTrees (TreeNode* root1, TreeNode* root2) { if (!root1 && !root2) return nullptr ; if (!root1 && root2) return root2; if (root1 && !root2) return root1; root1->val += root2->val; root1->left = mergeTrees (root1->left, root2->left); root1->right = mergeTrees (root1->right, root2->right); return root1; } };
700.二叉搜索树中的搜索
力扣题目地址
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class Solution {public : TreeNode* searchBST (TreeNode* root, int val) { if (!root) return nullptr ; if (root->val == val) return root; TreeNode *left = searchBST (root->left, val); if (left) return left; return searchBST (root->right, val); } };
98.验证二叉搜索树
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 class Solution {public : void inorder (TreeNode* t, vector<int >& res) { if (!t) return ; inorder (t->left, res); res.push_back (t->val); inorder (t->right, res); return ; } bool isValidBST (TreeNode* root) { vector<int > res; inorder (root, res); for (int i = 1 ; i < res.size (); i++) if (res[i - 1 ] >= res[i]) return false ; return true ; } };
530.二叉搜索树的最小绝对差
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 class Solution {public : void inorder (TreeNode* t, vector<int >& res) { if (!t) return ; inorder (t->left, res); res.push_back (t->val); inorder (t->right, res); return ; } int getMinimumDifference (TreeNode* root) { vector<int > res; inorder (root, res); int minDiff = INT_MAX; for (int i = 1 ; i < res.size (); i++) { int tmp = res[i] - res[i - 1 ]; minDiff = minDiff > tmp ? tmp : minDiff; } return minDiff; } };
501.二叉搜索树中的众数
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 class Solution {public : vector<int > majority; int curMSize = 0 ; int cnt = 0 ; int pre = INT_MIN; void inOrderTraverse (TreeNode* root) { if (!root) return ; inOrderTraverse (root->left); if (pre == root->val) cnt++; else cnt = 1 ; pre = root->val; printf ("%d %d\n" , curMSize, cnt); if (curMSize == cnt) majority.push_back (root->val); else if (curMSize < cnt) { vector <int >().swap (majority); majority.push_back (root->val); curMSize = cnt; } inOrderTraverse (root->right); } vector<int > findMode (TreeNode* root) { inOrderTraverse (root); return majority; } };
236. 二叉树的最近公共祖先
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Solution {public : TreeNode* lowestCommonAncestor (TreeNode* root, TreeNode* p, TreeNode* q) { if (root == p || root == q || root == NULL ) return root; TreeNode *left = lowestCommonAncestor (root->left, p, q); TreeNode *right = lowestCommonAncestor (root->right, p, q); if (left && !right) return left; if (!left && right) return right; if (left && right) return root; return nullptr ; } };
701.二叉搜索树中的插入操作
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 class Solution {public : TreeNode* insertIntoBST (TreeNode* root, int val) { if (!root) return root = new TreeNode (val); if (val < root->val) { if (!root->left) root->left = new TreeNode (val); else insertIntoBST (root->left, val); } if (val > root->val) { if (!root->right) root->right = new TreeNode (val); else insertIntoBST (root->right, val); } return root; } };
450.删除二叉搜索树中的节点
力扣题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 class Solution {public : TreeNode* deleteNode (TreeNode* root, int key) { if (!root) return root; if (root->val == key) { TreeNode *need2delete = root; if (!root->left && !root->right) root = nullptr ; else if (!root->left && root->right) root = root->right; else if (root->left && !root->right) root = root->left; else if (root->left && root->right) { TreeNode *tmp = root->right; while (tmp->left) tmp = tmp->left; tmp->left = root->left; root = root->right; } delete need2delete; } else { if (root->val > key) root->left = deleteNode (root->left, key); if (root->val < key) root->right = deleteNode (root->right, key); } return root; } };
八、图论
797.所有可能的路径
797. 所有可能的路径 - 力扣(LeetCode)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 class Solution {public : struct ArcNode { int adjvex; ArcNode *nextarc; ArcNode () : adjvex (0 ), nextarc (NULL ) {} }; struct VNode { ArcNode *nextarc; VNode () : nextarc (NULL ) {} }; vector<vector<int >> ans; void dfs (vector<int > &path, vector<VNode> vnode, int begin, int target) { for (ArcNode *p = vnode[begin].nextarc; p; p = p->nextarc) { path.push_back (p->adjvex); if (p->adjvex == target) { vector<int > copypath; copypath.assign (path.begin (), path.end ()); ans.push_back (copypath); path.pop_back (); continue ; } dfs (path, vnode, p->adjvex, target); path.pop_back (); } } vector<vector<int >> allPathsSourceTarget (vector<vector<int >>& graph) { vector<VNode> vnode (graph.size()) ; for (int i = 0 ; i < graph.size (); i++) { for (int k : graph[i]) { ArcNode *tmp = new (ArcNode); tmp->adjvex = k; tmp->nextarc = vnode[i].nextarc; vnode[i].nextarc = tmp; } } vector<int > path; path.push_back (0 ); dfs (path, vnode, 0 , graph.size ()-1 ); return ans; } };
200. 岛屿数量
200. 岛屿数量 - 力扣(LeetCode)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 class Solution {public : int directionX[4 ] = {-1 , 0 , 1 , 0 }; int directionY[4 ] = {0 , -1 , 0 , 1 }; bool check (int &i, int &j, int x, int y, int m, int n) { int tmpi = i + x, tmpj = j + y; if (tmpi <= -1 || tmpj <= -1 || tmpi >= m || tmpj >= n) return false ; i = tmpi; j = tmpj; return true ; } void dfs (vector<vector<char >> &grid, vector<vector<int >>& visited, int i, int j, int m, int n) { visited[i][j] = 1 ; for (int k = 0 ; k < 4 ; k++) { int x = directionX[k]; int y = directionY[k]; int tmpi = i, tmpj = j; if (check (tmpi, tmpj, x, y, m, n) == false ) continue ; if (visited[tmpi][tmpj] == 0 && grid[tmpi][tmpj] == '1' ) { dfs (grid,visited , tmpi, tmpj, m, n); } } } int numIslands (vector<vector<char >>& grid) { int ans = 0 ; int m = grid.size (); int n = grid[0 ].size (); vector<vector<int >> visited (m, vector <int >(n, 0 )); for (int i = 0 ; i < m; i++) { for (int j = 0 ; j < n ; j++) { if (visited[i][j] == 0 && grid[i][j] == '1' ) { ans++; dfs (grid, visited, i, j, m, n); } } } return ans; } };