leetcode笔记

82. Remove Duplicates from Sorted List II

  https://leetcode.com/problems/remove-duplicates-from-sorted-list-ii/

  下面代码是自写hashmap版,练一下hashmap,用一般的map<int,int>红黑树map也能过。

 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode(int x) : val(x), next(NULL) {}
 7  * };
 8  */
 9 
10 
11 class MyHash {
12     static const int MAX = 123456;
13     static const int MOD = 123447;
14     static const int WHAT = 1237;
15     static const int INVALID = -1234478;
16     pair<int,int> a[MAX];
17     bool used[MAX];
18     int siz =0;
19     int myhash(int key){
20         if(siz==MOD)return MOD;
21         int pos = key*WHAT%MOD;
22         while(pos<0)pos=-(pos+1);
23         while(used[pos] && a[pos].first!=key)pos = (pos+1)%MOD;
24         return pos;
25     }
26 public:
27     int insert(pair<int,int> kv){
28         int pos = myhash(kv.first);
29         if(pos==MOD)return -1;
30         if(!used[pos]){
31             used[pos]=true;
32             siz++;
33         }
34         a[pos] = kv;
35         return 0;
36     }
37     int get(int key){
38         int pos = myhash(key);
39         if(a[pos].first==key)return a[pos].second;
40         else return INVALID;
41     }
42 
43     void add(int key, int ad){
44         int pos = myhash(key);
45         if(!used[pos]){
46             insert(make_pair(key,0));
47         }
48         a[pos].second+=ad;
49     }
50 };
51  
52 class Solution {
53 public:
54     ListNode* deleteDuplicates(ListNode* head) {
55         MyHash count;
56         ListNode* cur = head;
57         while(cur!=NULL){
58             count.add(cur->val,1);
59             cur=cur->next;
60         }
61         ListNode newhead(0);
62         newhead.next = head;
63         cur=&newhead;
64         while(cur!=NULL){
65             while(cur->next !=NULL && count.get(cur->next->val)>1){
66                 cur->next = cur->next->next;
67             }
68             cur = cur->next;
69         }
70         return newhead.next;
71     }
72 };
View Code

 

106. Construct Binary Tree from Inorder and Postorder Traversal

  https://leetcode.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/

  根据中序后序建树。

  一般思想:后序里面越靠前面的越是根,找到中序的[st,ed]中最是根的,建个结点,再递归分支左结点、右结点。

  进一步思想:每次找最是根的那个要找区间最值,能不能直接找到那个根?根据后序遍历的规律,左子树的点和右子树的点肯定是分开的两部分,左边和右边,其中每部分的最后一个就是那个子树的根节点。

  

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Solution {
11     map<int,int> mp;
12     TreeNode* build(vector<int>& inorder, vector<int>& postorder, int inst, int ined , int post, int poed){
13         if(inst>ined || post>poed)return NULL;
14         int inmid = mp[postorder[poed]];
15         TreeNode * ret = new TreeNode(inorder[inmid]);
16         ret->left = build(inorder, postorder, inst, inmid-1, post, post + ((inmid-1) - inst));
17         ret->right = build(inorder, postorder, inmid+1, ined,poed - 1 - (ined - (inmid+1)),poed - 1);
18         return ret;
19     }
20 public:
21     TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
22         for(int i=0; i<inorder.size(); i++){
23             mp[inorder[i]] = i;
24         }
25         return build(inorder, postorder, 0, inorder.size()-1, 0, postorder.size()-1);
26     }
27 };
View Code

 

 

130. Surrounded Regions

  https://leetcode.com/problems/surrounded-regions/

  给一个矩阵,有X有O,把不与边界相连的O fill成X。

  宽搜。我深搜有的点RE了,可恶。

  宽搜代码:

  

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 class Solution {
 4     const int gx[4] = {1,-1,0,0};
 5     const int gy[4] = {0,0,1,-1};
 6     int n;
 7     int m;
 8     void fill(vector<vector<char>>&board , int x, int y,char c){
 9         queue<int> qx;
10         queue<int> qy;
11         qx.push(x);
12         qy.push(y);
13         board[x][y] = c;
14         while(!qx.empty()){
15             x = qx.front();
16             y = qy.front();
17             qx.pop();
18             qy.pop();
19             for(int i=0; i<4; i++){
20                 int xx = x+gx[i];
21                 int yy = y+gy[i];
22                 if(xx<0 || xx>=n || yy<0 || yy>=m)continue;
23                 if(board[xx][yy]=='X'|| board[xx][yy]=='1')continue;
24                 board[xx][yy] = c;
25                 qx.push(xx);
26                 qy.push(yy);
27             }
28         }
29     }
30 public:
31     void solve(vector<vector<char>>& board) {
32         if(board.empty())return;
33         n = board.size();
34         m = board[0].size();
35         for(int i=0; i<n; i++){
36             for(int j=0; j<m; j++){
37                 if((i==0 || j==0|| i==n-1 || j==m-1)&&board[i][j]=='O'){
38                     fill(board, i, j,'1');
39                 }
40             }
41         }
42         for(int i=1; i<n-1; i++){
43             for(int j=1; j<m-1; j++){
44                 if(board[i][j]=='O'){
45                     fill(board, i, j,'X');
46                 }
47             }
48         }
49         for(int i=0; i<n; i++){
50             for(int j=0; j<m; j++){
51                 if(board[i][j]=='1'){
52                     board[i][j] = 'O';
53                 }
54             }
55         }
56     }
57 };
58 
59 int main(){
60     vector<vector<char> >board ={{'O','O'},{'O','O'}};
61     Solution so;
62     so.solve(board);
63     return 0;
64 }
View Code

 

 

 137. Single Number II

  https://leetcode.com/problems/single-number-ii/

  好多数出现3次,只有一个数出现1次。

  解法:https://discuss.leetcode.com/topic/22821/an-general-way-to-handle-all-this-sort-of-questions

  代码:

  

 1 class Solution {
 2 public:
 3     int singleNumber(vector<int>& nums) {
 4         //00 01 10
 5         //01 10 00
 6         int a = 0;
 7         int b = 0;
 8         for(int x:nums){
 9             int na = (x & ~a & b) | (~x & a & ~b);
10             int nb = (x & ~b & ~a)| (~x & ~a & b);
11             a = na;
12             b = nb;
13         }
14         return ~a & b;
15     }
16 };
View Code

 

138. Copy List with Random Pointer

  https://leetcode.com/problems/copy-list-with-random-pointer/

  深拷贝带随机指针的链表。

  不用额外空间的方法:把A->B->C 各个节点复制一份放在旁边,A->A`->B->B`->C->C`,然后x`->random = x`->random->next。然后再把这个拆成两个链表。

  注意原来的链表不能破坏,要把它拆回原样。(我以为能随便乱搞,结果错了好久,可恶)

   

 1 /**
 2  * Definition for singly-linked list with a random pointer.
 3  * struct RandomListNode {
 4  *     int label;
 5  *     RandomListNode *next, *random;
 6  *     RandomListNode(int x) : label(x), next(NULL), random(NULL) {}
 7  * };
 8  */
 9 class Solution {
10 public:
11     RandomListNode *copyRandomList(RandomListNode *head) {
12         if(!head)return head;
13         RandomListNode *cur = head, *x,*t;
14         while(cur){
15             t = cur->next;
16             x = new RandomListNode(cur->label);
17             x->next = t;
18             x->random = cur->random;
19             cur->next = x;
20             cur = t;
21         }
22         cur = head;
23         while(cur){
24             cur = cur->next;
25             if(cur->random) cur->random = (cur->random)->next;
26             cur= cur->next;
27         }
28         x = head->next;
29         cur = head;
30         while(cur){
31             t = cur->next;
32             cur->next = cur->next->next;
33             if(cur->next)t->next = cur->next->next;
34             else t->next = NULL;
35             cur = cur->next;
36         }
37         return x;
38     }
39 };
View Code

 

 

146. LRU Cache

  https://leetcode.com/problems/lru-cache/

  LRU。每次满的时候把最久没用的那个踢出去。

  单链表+map,查找O(logn) 冲突O(n),因为要扫到最后一个。如果要冲突O(1)的话要双链表。

  

1 https://leetcode.com/problems/lru-cache/
View Code

 双向链表,把插入和删除函数抽了出来,好像不错:

 1 struct kvNode{
 2     int key;
 3     int val;
 4     kvNode *left, *right;
 5     kvNode(int k,int v):key(k), val(v),left(NULL), right(NULL){};
 6     kvNode():key(0),val(0),left(NULL),right(NULL){};
 7 };
 8 class LRUCache{
 9     int cnt = 0;
10     int ma;
11     kvNode h,tail;
12     map<int,kvNode*> mp;
13     void insert(kvNode* f, kvNode* now){;
14         now->left = f;
15         now->right = f->right;
16         f->right->left = now;
17         f->right = now;
18     }
19     void del(kvNode* now){
20         now->left->right = now->right;
21         now->right->left = now->left;
22     }
23 public:
24     LRUCache(int capacity) {
25         ma = capacity;
26         h.right=&tail;
27         tail.left = &h;
28         mp.clear();
29     }
30     
31     int get(int key) {
32         if(mp.find(key)!=mp.end()){
33             kvNode *p = mp[key];
34             del(p);
35             insert(&h, p);
36             return p->val;
37         }
38         return -1;
39     }
40     
41     void set(int key, int value) {
42         if(ma==0)return;
43         if(mp.find(key)==mp.end()){
44             if(cnt==ma){
45                 kvNode *q = tail.left;
46                 mp.erase(q->key);
47                 del(q);
48                 delete q;
49                 cnt--;
50             }
51             kvNode *p = new kvNode(key,value);
52             insert(&h,p);
53             mp[key] = p;
54             cnt++;
55         }else{
56             kvNode *p = mp[key];
57             p->val = value;
58             del(p);
59             insert(&h, p);
60         }
61     }
62 };
View Code

 

 

 

 

148. Sort List

 https://leetcode.com/problems/sort-list/

  链表排序。

  当然是用归并排序啦!都不用开多少新的空间。

  不过第一次写的时候,居然写错,可恶,有点难。

  关键在于,比如把AB分为A和B两份,我们要先存A之前的那个点aa、B之后的那个点bb,排完以后要他们连起来, aa->排完的->bb。

  为了更方便排,先要把他们切开,写一个split(node, length)函数,把node开始的length个结点之后变成null,把结尾之后的那个点返回。

  这样,就很容易排了!

  

 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode(int x) : val(x), next(NULL) {}
 7  * };
 8  */
 9 class Solution {
10     ListNode* merge(ListNode* l, ListNode *r){
11         ListNode temp(0);
12         ListNode *cur = &temp;
13         while(l && r){
14             if(l->val < r->val){
15                 cur->next = l;
16                 cur = l;
17                 l = l->next;
18             }else{
19                 cur->next = r;
20                 cur = r;
21                 r=r->next;
22             }
23         }
24         if(l){
25             cur->next = l;
26         }else cur->next = r;
27         cur = temp.next;
28         return cur;
29     }
30     
31     ListNode *split(ListNode *st, int w){
32         for(int i=1;st&& i<w; i++)st = st->next;
33         if(st==NULL)return NULL;
34         ListNode *p = st->next;
35         st->next = NULL;
36         return p;
37     }
38 public:
39     ListNode* sortList(ListNode* head) {
40         ListNode temp(0);
41         ListNode *hh = &temp;
42         hh->next = head;
43         int siz=0;
44         ListNode *cur = head;
45         while(cur){
46             siz++;
47             cur=cur->next;
48         }
49         for(int w=1; w<=siz; w*=2){
50             ListNode *tail = hh, *mid,*r;
51             while(tail->next){
52                 mid = split(tail->next,w);
53                 r = split(mid,w);
54                 tail->next = merge(tail->next, mid);
55                 for(int i=0;(tail->next)&& i<2*w; i++){
56                     tail = tail->next;
57                 }
58                 tail->next = r;
59             }
60         }
61         return hh->next;
62     }
63 };
View Code

 

 

 

168. Excel Sheet Column Title

171. Excel Sheet Column Number

  https://leetcode.com/problems/excel-sheet-column-title/

  https://leetcode.com/problems/excel-sheet-column-number/

  168是列数转excel列号,1对应A,27对应AA。

  171是反过来转,excel列号转列数。

  解:因为这个和进制有一点差别,没法直接把字母当做26进制,只好认真观察,瞪眼法。

  观察草稿:

 1 A 1 Z 26
 2 AA 27 = 26+1
 3 AZ 52 = 26 + 26
 4 BA 53 = 26*2 + 1
 5 ZA      26*26 + 1
 6 ZZ         26*26 + 26
 7 AAA        26*26 + 26 + 1
 8 AZZ        26*26 + 26*26 + 26
 9 
10 AA AZ -> A Z (X-1)%26
11 AA AZ -> A  (X-1) / 26
12 AAA AZZ -> AA AZ 
View Code

 

  168代码:

 1 class Solution {
 2 public:
 3     string convertToTitle(int n) {
 4         string ret = "";
 5         while(n){
 6             int x = (n-1)%26;
 7             char c = 'A'+x;
 8             ret = c+ret;
 9             n = (n-1)/26;
10         }
11         return ret;
12     }
13 };
View Code

 

  171代码:

 1 class Solution {
 2 public:
 3     int titleToNumber(string s) {
 4         int ans=0;
 5         int bei=1;
 6         for(int i = s.size()-1; i>=0; i--){
 7             int x = s[i]-'A' + 1;
 8             ans += bei*x;
 9             bei*=26;
10         }
11         return ans;
12     }
13 };
View Code

 

 

 

 

209. Minimum Size Subarray Sum

  https://leetcode.com/problems/minimum-size-subarray-sum/

  在数列中找 和大于等于s的连续子串 的最小长度。

  1.求和不能每次都直接一个个加(O(n)),可以像我这样弄一个求和数组求(O(1)),或者在滑动窗口的时候维护(可能比较麻烦,求和数组比较直接)。

  2.注意题目要求,如果没有满足需求的就返回0,包括数组为空的情况。

  3.一顿滑动

  4.补充:题目说做了O(n)的还要试试O(nlogn)的……what?看了别人的答案,O(n)的一般是滑动窗口不用求和数组,这样空间O(1)。O(nlogn)的是二分+求和数组的。

O(n):

 1 class Solution {
 2 public:
 3     vector<int> a;
 4     int sum(int st, int ed){
 5         return a[ed+1] - a[st];
 6     }
 7 
 8     int minSubArrayLen(int s, vector<int>& nums) {
 9         int siz = nums.size();
10         while(!a.empty())a.pop_back();
11         a.push_back(0);
12         for(int i=0; i<siz; i++)
13             a.push_back(a[i] + nums[i]);
14         int r=0,l=0;
15         while(sum(l,r)<s && r<siz)r++;
16         if(r>=siz)return 0;
17         int ans = r-l+1;
18         for(;r<siz;r++){
19             while(r>l && sum(l+1,r)>=s)l++;
20             ans = min(r-l+1, ans);
21         }
22         return ans;
23     }
24 };
View Code

 

O(nlogn):

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 class Solution {
 4 public:
 5     vector<int> a;
 6     int sum(int st, int ed) {
 7         return a[ed+1] - a[st];
 8     }
 9 
10     int bs(int st,int ed, int s){
11         int l=st, r=ed;
12         int re = INT_MAX;
13             while(l<=r){
14                 int mid = l + (r-l)/2;
15                 if(sum(st,mid)>=s)
16                     r=mid-1;
17                 else l=mid+1;
18             }
19         if(l<=ed)re=l;
20         return re;
21     }
22 
23     int minSubArrayLen(int s, vector<int>& nums) {
24         int siz = nums.size();
25         while(!a.empty())a.pop_back();
26         a.push_back(0);
27         for(int i=0; i<siz; i++)
28             a.push_back(a[i] + nums[i]);
29         int ans = INT_MAX;
30         for(int st=0; st<siz; st++){
31             int x = bs(st,siz-1,s);
32             if(x!=INT_MAX)
33                 ans = min(ans,x - st + 1);
34         }
35         return ans!=INT_MAX?ans:0;
36     }
37 };
38 
39 int main(){
40     int s=7;
41     int arr[]={2,3,1,2,4,3};
42     vector<int> v(arr,arr+6);
43     Solution so;
44     int ans = so.minSubArrayLen(s,v);
45     printf("%d\n",ans);
46     return 0;
47 }
View Code

 

 

 

211. Add and Search Word - Data structure design 

  https://leetcode.com/problems/add-and-search-word-data-structure-design/

  做一个数据结构,支持插入字符串和判断字符串是否在,判断时支持用点.代替任意字母,其他的只能是a到z小写字母。

  解:用字典树,遇到点的时候用26种递归去找。

  

 1 class TrieNode{
 2 public:
 3     bool isKey;
 4     TrieNode* child[26];
 5     TrieNode():isKey(false){
 6         memset(child,NULL, sizeof(child));
 7     }
 8 };
 9 
10 class WordDictionary {
11     TrieNode root;
12     bool find(const char *s, TrieNode *cur){
13         int j=0;
14         while(s[j]){
15             char c = s[j];
16             if(c!='.'){
17                 int q = c - 'a';
18                 if(cur->child[q]) cur = cur->child[q];
19                 else return false;
20             }else{
21                 for(int i=0; i<26; i++){
22                     if(cur->child[i]){
23                         if(find(s+j+1, cur->child[i])) return true;
24                     }
25                 }
26                 return false;
27             }
28             j++;
29         }
30         if(cur->isKey)return true;
31         else return false;
32     }
33 public:
34 
35     // Adds a word into the data structure.
36     void addWord(string word) {
37         TrieNode* cur = &root;
38         for(char c:word){
39             int q = c - 'a';
40             if(cur->child[q] == NULL){
41                 cur ->child[q] = new TrieNode();
42             }
43             cur = cur->child[q];
44         }
45         cur->isKey = true;
46     }
47 
48     // Returns if the word is in the data structure. A word could
49     // contain the dot character '.' to represent any one letter.
50     bool search(string word) {
51         return find(word.c_str(), &root);
52     }
53 };
54 
55 // Your WordDictionary object will be instantiated and called as such:
56 // WordDictionary wordDictionary;
57 // wordDictionary.addWord("word");
58 // wordDictionary.search("pattern");
View Code

 

 

 

227. Basic Calculator II

  https://leetcode.com/problems/basic-calculator-ii/

  表达式求值,加减乘除,不带括号。

  可恶,看了题解,发现这个不带括号的直接瞎比做就行了,我还想什么栈方法什么递归方法想了半天,简直逗,题解都是只要十几行的。

  下面是没看题解写的。

  =============分割线============

  随机到这题发现我真的弱,这是基础题啊,我都不记得怎么做,需要认真复习了。

  方法两种:

  1.先用一个符号栈中缀转后缀,再用一个操作数栈进行后缀表达式求值。

  2.用两个栈,一个符号栈一个操作数栈,直接对中缀表达式求值。

  中缀转后缀的代码:

 1 class Solution {
 2     map<char,int> priority;
 3     int cal(vector<int> v){
 4         stack<int> s;
 5         for(int x:v){
 6             if(x>=0)s.push(x);
 7             else{
 8                     char c = -x;
 9                     int z = s.top();
10                     s.pop();
11                     int y = s.top();
12                     s.pop();
13                     int w;
14                     switch(c){
15                         case '+':
16                             w = y+z;
17                             break;
18                         case '-':
19                             w=y-z;
20                             break;
21                         case '*':
22                             w=y*z;
23                             break;
24                         case '/':
25                             w=y/z;
26                             break;
27                     }
28                     s.push(w);
29                 }
30             }
31         return s.top();
32     }
33     
34     vector<int> mid2back(vector<int> v){
35         vector<int> ret;
36         stack<char> s;
37         for(int x:v){
38             if(x>=0)ret.push_back(x);
39             else{
40                 char c = -x;
41                 while(!s.empty() && priority[s.top()]>=priority[c]){
42                     ret.push_back(-s.top());
43                     s.pop();
44                 }
45                 s.push(c);
46             }
47         }
48         while(!s.empty()){
49             ret.push_back(-s.top());
50             s.pop();
51         }
52         return ret;
53     }
54     
55     vector<int> str2vec(string s){
56         vector<int> ret;
57         int num=0;
58         for(char c:s){
59             if(c==' ')continue;
60             if(c>='0' && c<='9') num = num*10 + (c - '0');
61             else {
62                 ret.push_back(num);
63                 num=0;
64                 char ch = c;
65                 ret.push_back(-c);
66             }
67         }
68         ret.push_back(num);
69         return ret;
70     }
71     
72 public:
73     Solution(){
74         priority['*']=2;
75         priority['/']=2;
76         priority['+']=1;
77         priority['-']=1;
78     }
79 
80     int calculate(string s) {
81         vector<int> midexp = str2vec(s);
82         vector<int> backexp = mid2back(midexp);
83         int ans = cal(backexp);
84         return ans;
85     }
86 };
View Code

  思考:如果带括号怎么做?中缀转后缀的时候就要将括号消掉了,遇到右括号就要疯狂出栈直到消掉左括号。难道是左右括号优先级1,加减2,乘除3?特殊处理弹出左括号的时候就结束while,并且右括号不入栈,好像不错。不对,这样入左括号的时候,之前的就要弹光了,难道左括号特殊处理不管优先级就进站?好像可以。

 

312. Burst Balloons

  https://leetcode.com/problems/burst-balloons/

  有一排乘法恐狼先锋,你杀一个i号狼会收到a[i-1]*a[i]*a[i+1]的伤害,然后剩下的会连起来。求能受到的最大伤害。

  和hdu 5115 Dire Wolf 题解 (ACM/ICPC 14 北京站 现场赛)  差不多。别人的题解:http://blog.163.com/infog@126/blog/static/783768072014114714157/

  区间DP代码:

  

 1 class Solution {
 2 public:
 3     int maxCoins(vector<int>& nums) {
 4         int f[nums.size()+1][nums.size()+1];
 5         memset(f,0,sizeof(f));
 6         int n=nums.size();
 7         for(int k=0; k<n; k++){
 8             for(int i=0; i+k<n; i++){
 9                 int t=1;
10                 if(i-1>=0)t*=nums[i-1];
11                 if(i+k+1<n)t*=nums[i+k+1];
12                 for(int j=i; j<=i+k; j++){
13                     f[i][i+k] = max(f[i][i+k], f[i][j-1] + f[j+1][i+k] + t*nums[j]);
14                 }
15             }
16         }
17         return f[0][n-1];
18     }
19 };
View Code

 

352. Data Stream as Disjoint Intervals

https://leetcode.com/problems/data-stream-as-disjoint-intervals/

  做一个数据结构,支持插入数字,输出一堆区间。

  用一个map记各个数字,指向Interval编号。

  插入数字的时候维护区间左右端点, 合并区间的时候删Interval。

  注意不仅要维护左右端点,当前插入点也要记一下,不然会重复插入,我这个错找了好久。 

 1 /**
 2  * Definition for an interval.
 3  * struct Interval {
 4  *     int start;
 5  *     int end;
 6  *     Interval() : start(0), end(0) {}
 7  *     Interval(int s, int e) : start(s), end(e) {}
 8  * };
 9  */
10 class SummaryRanges {
11     map<int,int> mp;
12     map<int,Interval>itv;
13     int n=0;
14 public:
15     /** Initialize your data structure here. */
16     SummaryRanges() {
17         mp.clear();
18         itv.clear();
19         n=0;
20     }
21     
22     void addNum(int val) {
23         if(mp.find(val)==mp.end()){
24             int l =val;
25             int r = val;
26             if(mp.find(val-1)!=mp.end()) l = min(l, itv[mp[val-1]].start);
27             if(mp.find(val+1)!=mp.end()) r = max(r, itv[mp[val+1]].end);
28             if(l==r){
29                 itv[n] = Interval(val,val);
30                 mp[val]=n;
31                 n++;
32             }else if(l!=val && r!=val){
33                 itv.erase(mp[r]);
34                 itv[mp[l]].start = l;
35                 itv[mp[l]].end = r;
36                 mp[r]=mp[l];
37                 mp[val]=mp[l];// use for judge if val insert before
38             }else{
39                 int x = (l==val)?r:l;
40                 itv[mp[x]].start = l;
41                 itv[mp[x]].end = r;
42                 mp[val] = mp[x];
43             }
44         }
45     }
46     
47     static bool cmp(const Interval &x,const Interval &y){
48         return x.start < y.start;
49     }
50     
51     vector<Interval> getIntervals() {
52         vector<Interval> ret;
53         for(pair<int,Interval> it:itv){
54             ret.push_back(it.second);
55         }
56         sort(ret.begin(), ret.end(), cmp);
57         return ret;
58     }
59 };
60 
61 /**
62  * Your SummaryRanges object will be instantiated and called as such:
63  * SummaryRanges obj = new SummaryRanges();
64  * obj.addNum(val);
65  * vector<Interval> param_2 = obj.getIntervals();
66  */
View Code

 

 

 

 

374. Guess Number Higher or Lower

https://leetcode.com/problems/guess-number-higher-or-lower/

幸运52猜数字,注意点:1.C++ 爆int,平均数要用x = l + (r-l)/2;

            2.当l==r时就不用再猜一次了可以直接return。(不关键)

 

 

394. Decode String

https://leetcode.com/problems/decode-string/

递归:

 1 class Solution {
 2     string decode(string s, int &i){
 3         int cnt=0;
 4         string ret = "";
 5         for(; s[i]!=']'; i++){
 6             if(s[i]>='0' && s[i]<='9'){
 7                 cnt = cnt *10 + (s[i]-'0');
 8             }else if(s[i]=='['){
 9                 i++;
10                 string t = decode(s,i);
11                 for(int j=0; j<cnt; j++)
12                     ret += t;
13                 cnt = 0;
14             }else ret += s[i];
15         }
16         return ret;
17     }
18 public:
19     string decodeString(string s) {
20         int i=0;
21         return decode(s+"]", i);
22     }
23 };
View Code

 

非递归:

 1 class Solution {
 2 public:
 3     string decodeString(string s) {
 4         int i=0;
 5         stack<int> si;
 6         stack<string> ss;
 7         string t="";
 8         int cnt = 0;
 9         for(char c:s){
10             if(c>='0' && c<='9'){
11                 cnt = cnt *10 + (c-'0');
12             }else if(c=='['){
13                 si.push(cnt);
14                 cnt=0;
15                 ss.push(t);
16                 t="";
17             }else if(c==']'){
18                 cnt = si.top();
19                 si.pop();
20                 string tt = t;
21                 t = ss.top();
22                 ss.pop();
23                 for(int j=0; j<cnt; j++)
24                     t += tt;
25                 cnt = 0;
26             }else t += c;
27         }
28         return t;
29     }
30 };
View Code

 

 

450. Delete Node in a BST

  https://leetcode.com/problems/delete-node-in-a-bst/

  删除二叉搜索树中的一点。又不用平衡,随便搞搞,虽然我搞错了好久……

  

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Solution {
11     int deleteLittle(TreeNode * cur){
12         TreeNode * fa = cur;
13         while(cur->left!=NULL){
14             fa = cur;
15             cur = cur->left;
16         }
17         int ret = cur->val;
18         fa->left = cur->right;//this, I wrote wrong : fa->left = NULL, ouch! spend much time to find and fix it.
19         return ret;
20     }
21 public:
22     TreeNode* deleteNode(TreeNode* root, int key) {
23         if(!root)return NULL;
24         if(root->val ==key){
25             if(!root->left)return root->right;
26             if(!root->right)return root->left;
27             if((root->right)->left!=NULL){
28                 root->val = deleteLittle(root->right);
29             }else{
30                 root->val = root->right->val;
31                 root->right = root->right->right;
32             }
33         }else{
34             if(key < root->val){
35                 root->left = deleteNode(root->left, key);
36             }else 
37                 root->right = deleteNode(root->right, key);
38         }
39         return root;
40     }
41 };
View Code

 

 

 

460. LFU Cache

  https://leetcode.com/problems/lfu-cache/

  LFU,Least Frequently Used (LFU) ,是冲突时先删频率最小的,频率相同的话删最久没用过的。(另外一种叫LRU,就是删最久没用过的)。

  做完发现怎么是hard,可恶,不过复习了LRU LFU的概念。

  这个关键是,冲突时怎么找到最小的那个。每次冲突都要找最小的,很容易想到需要一个能够支持插入、删除、快速找到最小的这三中操作的数据结构,这不就是,map嘛,底层是红黑树实现,插入删除查找都是Logn,无敌。如果是每次在数组里扫最小的,那是O(n)。

  另外用key找value,这个我也用的map,总的时间复杂度大概,查找是logn,插入时冲突,也是logn,好像是这个样子,每次操作logn,m次操作mlogn。

  题目提示说要O(1)操作,那key找value可以hash,这个找最小要怎么O(1)?等我想一想。

  logn代码:

  

 1 class LFUCache {
 2     int capa;
 3     int used;
 4     typedef pair<pair<int,int>,pair<int,int> > p4i;// frequency, time, key, value
 5     vector<p4i> v;  //v[pos]
 6     map<int,int> mp;    //<key, pos>
 7     map<pair<int,int>, int> freqTimePos;    // frequency, time , pos
 8     int time;
 9 public:
10     LFUCache(int capacity) {
11         capa = capacity;
12         used=0;
13         time=0;
14         v.clear();
15         mp.clear();
16     }
17     
18     int get(int key) {
19         if(mp.find(key)!=mp.end()){
20             time++;
21             int p = mp[key];
22             freqTimePos.erase(v[p].first);
23             v[p].first.second = time;
24             v[p].first.first++;
25             freqTimePos[v[p].first]=p;
26             return v[p].second.second;
27         }else return -1;
28     }
29     
30     void put(int key, int value) {
31         time++;
32         if(mp.find(key)!=mp.end()){
33             int p = mp[key];
34             freqTimePos.erase(v[p].first);
35             v[p].first.second = time;
36             v[p].first.first++;
37             freqTimePos[v[p].first]=p;
38             v[p].second.second = value;
39         }else{
40             if(used<capa){
41                 used++;
42                 v.push_back(make_pair(make_pair(1,time),make_pair(key,value)));
43                 freqTimePos[v.back().first]=v.size()-1;
44                 mp[key]=v.size()-1;
45             }else{
46                 if(capa==0)return;
47                 int ekey,epos;
48                 map<pair<int,int>, int>::iterator it = freqTimePos.begin();
49                 epos = it->second;
50                 ekey = v[epos].second.first;
51                 mp.erase(ekey);
52                 mp[key]=epos;
53                 freqTimePos.erase(v[epos].first);
54                 v[epos] = make_pair(make_pair(1,time),make_pair(key,value));
55                 freqTimePos[v[epos].first]=epos;
56             }
57         }
58     }
59 };
60 
61 /**
62  * Your LFUCache object will be instantiated and called as such:
63  * LFUCache obj = new LFUCache(capacity);
64  * int param_1 = obj.get(key);
65  * obj.put(key,value);
66  */
View Code

 

posted @ 2016-12-27 09:25  带鱼Yuiffy  阅读(352)  评论(0编辑  收藏  举报