牛客网与leetcode刷题(高频题中简单or中等的)
目錄
- 1、反轉鏈表
- 2、排序
- 3、先序中序后序遍歷
- 4、最小的k個數
- 5、子數組的最大累加和
- 6、 用兩個棧實現隊列
- 7、142. 環形鏈表 II
- 8、20. 有效的括號
- 9、最長公共子串(動態規劃),磕磕絆絆
- 10、二叉樹之字形層序遍歷
- 11、重建二叉樹
- 12、LRU緩存
- 13、合并兩個有序鏈表
- 15、大數加法
- 16、一個二叉樹和一個值sum,請找出所有的根節點到葉子節點的節點值之和等于sum 的路徑
- 17、尋找第K大
- 18、買賣股票的最佳時機
- 19、二數之和
- 20、合并兩個有序數組
- 21、二叉樹的最近公共祖先
感覺所有算法里面掌握最好的還是回溯,其他的都是半吊子。
1、反轉鏈表
反轉鏈表
雙指針法
2、排序
排序
這里我們選擇使用快速排序來求解:
3、先序中序后序遍歷
遞歸法:
class Solution { public:/*** * @param root TreeNode類 the root of binary tree* @return int整型vector<vector<>>*/vector<int> pre;vector<int> mid;vector<int> post;void preorder(TreeNode* root){if(root == nullptr) return;pre.push_back(root->val);preorder(root->left);preorder(root->right);}void midorder(TreeNode* root){if(root == nullptr) return;midorder(root->left);mid.push_back(root->val);midorder(root->right);}void postorder(TreeNode* root){if(root == nullptr) return;postorder(root->left);postorder(root->right);post.push_back(root->val);}vector<vector<int> > threeOrders(TreeNode* root) {// write code herepre.clear();mid.clear();post.clear();preorder(root);midorder(root);postorder(root);return {pre,mid,post};} };4、最小的k個數
sort + 取值
class Solution { public:vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {if(k > input.size()) return {};vector<int> result(k,0);sort(input.begin(),input.end());for(int i = 0; i < k; i++)result[i] = input[i];return result;} };方法二:堆
我們用一個大根堆實時維護數組的前 k 小值。首先將前 k個數插入大根堆中,隨后從第 k+1 個數開始遍歷,如果當前遍歷到的數比大根堆的堆頂的數要小,就把堆頂的數彈出,再插入當前遍歷到的數。最后將大根堆里的數存入數組返回即可。在下面的代碼中,由于 C++ 語言中的堆(即優先隊列)為大根堆,我們可以這么做。
如果是要求最大的k個數,就用小根堆
5、子數組的最大累加和
https://leetcode-cn.com/problems/lian-xu-zi-shu-zu-de-zui-da-he-lcof/
class Solution { public:int maxSubArray(vector<int>& nums) {if(nums.empty()) return 0;int res =INT_MIN;int sum = 0;for(int i = 0; i < nums.size(); i++){sum += nums[i];if(sum > res) res = sum;if(sum < 0) sum = 0;}return res;} };6、 用兩個棧實現隊列
用兩個棧實現隊列
一個輸入棧,一個輸出棧。
push數據的時候,只要把數據放進輸入棧即可。
pop的時候:
1、輸出棧如果為空,就將進棧的數據全部導入,再出棧彈出數據。
2、如果棧不為空,直接從出棧彈出數據
7、142. 環形鏈表 II
環形鏈表 II
使用快慢指針:
通過數學證明,x = z;
即:從頭節點出發一個index,從相遇地點出發一個index,每次移動一點,直到兩者相遇,相遇地點就是入口
這里給出牛客網同樣題目的代碼:
https://www.nowcoder.com/practice/6e630519bf86480296d0f1c868d425ad?tpId=117&tqId=37713&companyId=134&rp=1&ru=%2Fcompany%2Fhome%2Fcode%2F134&qru=%2Fta%2Fjob-code-high%2Fquestion-ranking&tab=answerKey
8、20. 有效的括號
https://leetcode-cn.com/problems/valid-parentheses/
使用棧的時候三者對應到的棧的情況;
1、已經遍歷完字符串,但是棧不為空
2、遍歷字符串匹配的過程中,棧已經為空了
3、再遍歷字符串匹配的過程中,發現棧中沒有要匹配的字符。
9、最長公共子串(動態規劃),磕磕絆絆
給定兩個字符串str1和str2,輸出兩個字符串的最長公共子串
題目保證str1和str2的最長公共子串存在且唯一。
1≤∣str1∣,∣str2∣≤5000
“1AB2345CD”,“12345EF”
“2345”
1、把兩個字符串分別以行和列組成一個二維矩陣。
2、比較二維矩陣中每個點對應行列字符中否相等,相等的話值設置為1,否則設置為0。
3、通過查找出值為1的最長對角線就能找到最長公共子串。
10、二叉樹之字形層序遍歷
層序遍歷+flag標志即可
vector<vector<int> > zigzagLevelOrder(TreeNode* root) {// write code herequeue<TreeNode*> que;if(root != nullptr) que.push(root);vector<vector<int>> result;int flag = 0;while(!que.empty()){int size = que.size();vector<int> vec;for(int i = 0; i < size; i++){TreeNode* node = que.front();que.pop();vec.push_back(node->val);if(node->left) que.push(node->left);if(node->right) que.push(node->right);}if(flag == 0){result.push_back(vec);flag = 1;}else{reverse(vec.begin(),vec.end());result.push_back(vec);flag = 0;}}return result;}11、重建二叉樹
https://leetcode-cn.com/problems/zhong-jian-er-cha-shu-lcof/
/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/ class Solution { public:TreeNode* traversal(vector<int>& preorder,int prestart,int preend,vector<int>& inorder,int instart,int inend){//首先,檢查先序數組大小,根據下標if(prestart == preend){return nullptr;}//先序數組中第一個節點就是當前中間節點,new一個節點int rootval = preorder[prestart];TreeNode* root = new TreeNode(rootval);//如果是葉子節點,就不需要分割了,直接返回該節點if(preend - prestart == 1){return root;}//中序數組找切割點int splitIndex = instart; //注意,區間是左閉右開的for(splitIndex = instart; splitIndex < inend; splitIndex++){if(inorder[splitIndex] == rootval) break;}//切割中序數組int leftInbegin = instart;int leftInend = splitIndex;int rightInbegin = splitIndex + 1;int rightInend = inend;//切割先序數組int leftPrebegin = prestart + 1;int leftPreend = prestart + leftInend - leftInbegin;int rightPrebegin = leftPreend;int rightPreend = preend;//遞歸處理左區間和右區間root->left = traversal(preorder,leftPrebegin,leftPreend,inorder,leftInbegin,leftInend);root->right = traversal(preorder,rightPrebegin,rightPreend,inorder,rightInbegin,rightInend);return root;}TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {if(preorder.empty() || inorder.empty()) return nullptr;return traversal(preorder,0,preorder.size(),inorder,0,inorder.size());} };12、LRU緩存
struct DLinkedNode { public:int key;int value;DLinkedNode* prev;DLinkedNode* next;DLinkedNode() : key(0), value(0), prev(nullptr), next(nullptr) {};DLinkedNode(int _key, int _value) : key(_key), value(_value), prev(nullptr), next(nullptr) {}; }; class LRUCache { private:unordered_map<int,DLinkedNode*> cache;//dummyhead and dummytailDLinkedNode* dummyhead;DLinkedNode* dummytail;// now size of cacheint _size;// capacity of cacheint _capacity; public:LRUCache(int capacity) {_capacity = capacity;_size = 0;dummyhead = new DLinkedNode();dummytail = new DLinkedNode();dummyhead->next = dummytail;dummytail->prev = dummyhead;}~LRUCache() {delete dummyhead;delete dummytail;}int get(int key) {// if not findif(cache.find(key) == cache.end()){return -1;}//if find//haxi DLinkedNode* node = cache[key];//move this Node to headmoveHead(node);return node->value;}void put(int key, int value) {// if key not exist ,create itif(cache.find(key) == cache.end()){// if size > capacity delete tail nodeif(_size + 1 > _capacity){DLinkedNode* deleted_node = deleteTail();cache.erase(deleted_node->key);delete deleted_node;_size--;}DLinkedNode* newnode = new DLinkedNode(key,value);cache[key] = newnode;addHead(newnode);_size++;}else //chage value{DLinkedNode* node = cache[key];node->value = value;moveHead(node);}}void addHead(DLinkedNode* node){//雙向指針操作 + 虛擬頭節點node->prev = dummyhead;node->next = dummyhead->next;dummyhead->next->prev = node;dummyhead->next = node;}DLinkedNode* deleteTail(){//尾節點是虛擬tail前面一個。DLinkedNode* node = dummytail->prev;deleteNode(node);return node;}void deleteNode(DLinkedNode* node){node->prev->next = node->next;node->next->prev = node->prev;}void moveHead(DLinkedNode* node){//先刪除當前節點deleteNode(node);//然后將它加入頭部addHead(node);} };13、合并兩個有序鏈表
https://leetcode-cn.com/problems/merge-two-sorted-lists/
/*** Definition for singly-linked list.* 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) {}* };*/ class Solution { public:ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {ListNode* dummyHead = new ListNode(-1);ListNode* cur = dummyHead;while(l1 != nullptr && l2 != nullptr){if(l1->val > l2->val){cur->next = l2;cur = cur->next;l2 = l2->next;}else{cur->next = l1;cur = cur->next;l1 = l1->next;}} while(l1 != nullptr) {cur->next = l1;cur = cur->next;l1 = l1->next;}while(l2 != nullptr){cur->next = l2;cur = cur->next;l2 = l2->next;}ListNode* ret = dummyHead->next;delete dummyHead;return ret;} };15、大數加法
大數加法
class Solution { public:/*** 代碼中的類名、方法名、參數名已經指定,請勿修改,直接返回方法規定的值即可* 計算兩個數之和* @param s string字符串 表示第一個整數* @param t string字符串 表示第二個整數* @return string字符串*/string solve(string s, string t) {// write code hereif(s.empty()) return t;if(t.empty()) return s;if(s.size()<t.size()) swap(t,s);int tail = s.size() - t.size();int tmp = 0;//補零操作 t是短的那個while(tail--) t = '0'+t;//每次只處理1位,從低到高for(int i=s.size()-1;i>=0;i--){tmp = s[i]-'0' + t[i] -'0' + tmp;s[i] = tmp%10 + '0';tmp/=10;}//最高位是否有進位位if(tmp) s = '1'+s;return s;} };16、一個二叉樹和一個值sum,請找出所有的根節點到葉子節點的節點值之和等于sum 的路徑
一個二叉樹和一個值sum…
普通的回溯即可。
17、尋找第K大
18、買賣股票的最佳時機
int maxProfit(vector<int>& prices) {// write code hereint n = prices.size();vector<int> dp(n+1,0);int minnum = prices[0];for(int i = 1; i < n; i++){minnum = min(minnum,prices[i]);dp[i] = max(prices[i] - minnum,dp[i-1]);}return dp[n-1];}可以使用滾動數組優化:
int maxProfit(vector<int>& prices) {int n=prices.size();if(n==0) return 0;int ans=0;int minnum =prices[0];for(int i=1;i<n;i++){minnum=min(minnum,prices[i]);ans=max(ans,prices[i]-minnum);}if(ans<=0)ans=0;return ans;}19、二數之和
https://leetcode-cn.com/problems/two-sum/
class Solution { public:vector<int> twoSum(vector<int>& nums, int target) {unordered_map<int,int > umap;for(int i = 0; i < nums.size(); i++){auto iter = umap.find(target - nums[i]);//如果找到了if(iter != umap.end()){return {i,iter->second};}//否則,進行插入操作umap.insert(pair<int,int>(nums[i],i));}return {};} };20、合并兩個有序數組
void merge(int A[], int m, int B[], int n) {int l1 = 0;int l2 = 0;vector<int> res;while(l1 < m && l2 < n){if(A[l1] <= B[l2]){res.push_back(A[l1]);l1++;}else{res.push_back(B[l2]);l2++;}}while(l1 < m) {res.push_back(A[l1]);l1++;}while(l2 < n) {res.push_back(B[l2]);l2++;}for(int i = 0; i < res.size(); i++)A[i] = res[i];}21、二叉樹的最近公共祖先
NC二叉樹的最近公共祖先
int lowestCommonAncestor(TreeNode* root, int o1, int o2) {// write code hereif(root == nullptr) return -1;if(o1 == root->val || o2 == root->val) return root->val;int left = lowestCommonAncestor(root->left,o1,o2);int right = lowestCommonAncestor(root->right,o1,o2);if(left == -1) return right;if(right == -1) return left;return root->val;}總結
以上是生活随笔為你收集整理的牛客网与leetcode刷题(高频题中简单or中等的)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 这个视频背景音乐叫啥?跪求!!
- 下一篇: 绿水青山好日子剧情介绍