Leetcode模拟题篇

43. Multiply Strings

高精度非负整数的乘法。

 1 string multiply(string num1, string num2) {
 2     string sum(num1.size() + num2.size(), '0');
 3     
 4     for (int i = num1.size() - 1; 0 <= i; --i) {
 5         int carry = 0;
 6         for (int j = num2.size() - 1; 0 <= j; --j) {
 7             int tmp = (sum[i + j + 1] - '0') + (num1[i] - '0') * (num2[j] - '0') + carry;
 8             sum[i + j + 1] = tmp % 10 + '0';
 9             carry = tmp / 10;
10         }
11         sum[i] += carry;
12     }
13     
14     size_t startpos = sum.find_first_not_of("0");
15     if (string::npos != startpos) {
16         return sum.substr(startpos);
17     }
18     return "0";
19 }
View Code
 1     string multiply(string num1, string num2) {
 2         int i, j;
 3         int m = num1.size(), n = num2.size();
 4         // max (m + n) digits
 5         vector<int> product(m + n, 0);
 6         string result;
 7 
 8         // reverse for ease of calc
 9         reverse(num1.begin(), num1.end());
10         reverse(num2.begin(), num2.end());
11 
12         // digit i * digit j contributes to digit i + j
13         for (i = 0; i < m; i++) {
14             for (j = 0; j < n; j++) {
15                 product[i + j] += (num1[i] - '0') * (num2[j] - '0');
16                 product[i + j + 1] += product[i + j] / 10;
17                 product[i + j] %= 10;
18             }
19         }
20 
21         // remove leading 0; keep last 0 if all 0
22         for (i = m + n - 1; i > 0 && 0 == product[i]; i--);
23         
24         for (; i >= 0; i--)
25             result += to_string(product[i]);
26 
27         return result;
28     }
View Code

 

224. Basic Calculator

包含()+-、空格的非负整数的表达式求值。

 1     int calculate(string s) {
 2         stack <int> nums, ops;
 3         int num = 0;
 4         int rst = 0;
 5         int sign = 1;
 6         for (char c : s) { 
 7             if (isdigit(c)) {
 8                 num = num * 10 + c - '0';
 9             }
10             else {
11                 rst += sign * num;
12                 num = 0;
13                 if (c == '+') sign = 1;
14                 if (c == '-') sign = -1;
15                 if (c == '(') {
16                     nums.push(rst);
17                     ops.push(sign);
18                     rst = 0;
19                     sign = 1;
20                 }
21                 if (c == ')' && ops.size()) {
22                     rst = ops.top() * rst + nums.top();
23                     ops.pop(); nums.pop();
24                 }
25             }
26         }
27         rst += sign * num;
28         return rst;
29     }
View Code
 1 class Solution {
 2 public:
 3     int calculate(string s) {
 4         int n = s.size();
 5         stack<int> s1;
 6         stack<char> s2;
 7         string v;
 8         for(int i = n - 1; i >= 0; i--){
 9             if(s[i] == ')' || s[i] == '+' || s[i] == '-') s2.push(s[i]);
10             else if(s[i] >= '0' && s[i] <= '9'){
11                 v = s[i] + v;
12                 if(i == 0 || s[i - 1] < '0' || s[i - 1] > '9'){
13                     s1.push(stoi(v)); 
14                     v = "";
15                 }
16             } else if(s[i] == '('){
17                 while(s2.top() != ')') cal(s1, s2);
18                 s2.pop();
19             }
20         }
21         while(!s2.empty()) cal(s1, s2);
22         return s1.top();
23     }
24 
25     void cal(stack<int> &s1, stack<char> &s2){
26         int v1 = s1.top(); s1.pop();
27         int v2 = s1.top(); s1.pop();
28         char c = s2.top(); s2.pop();
29         if(c == '+') s1.push(v1 + v2);
30         if(c == '-') s1.push(v1 - v2);
31     }
32 };
View Code

 

227. Basic Calculator II

包含+-*/、空格的非负整数的表达式求值。

 1 int calculate(string s) {
 2        stack<char> opS;
 3        stack<int>  numS;
 4        s.push_back(')'); // to make sure the last operand will be saved in the stack e.g. 1+2*3), 2*3 will be calculated and push in the stack
 5        opS.push('+'); // sign for the first operand
 6        
 7        int i, curNum, len = s.size(), res =0;
 8        for(i=0,curNum=0; i<len; ++i)
 9        {
10            if(isdigit(s[i])) curNum = curNum*10 + s[i] -'0'; // digit, recover the oprand
11            else if(isspace(s[i])) continue; // skip the space
12            else
13            {
14                switch(opS.top())
15                { 
16                    case '*': // if the last operator is * / , do calculation
17                    case '/':
18                         curNum = opS.top()=='/'?numS.top()/curNum : numS.top()*curNum;
19                         opS.pop();
20                         numS.pop();
21                }
22                 numS.push(curNum); /
23                 curNum = 0;
24                 opS.push(s[i]);
25            }
26        }
27        opS.pop(); // skip the ")"
28        while(!opS.empty()) {res += (opS.top()=='-')? -numS.top(): numS.top(); opS.pop(); numS.pop();}
29        return res;
30     }
View Code

附含括号的代码:

 1     int calculate(string s) {
 2        stack<char> opS;
 3        stack<int>  numS;
 4        s = '(' + s + ')';
 5 
 6        int i, curNum = 0, len = s.size();
 7        for(i=0; i<len; ++i)
 8        {
 9            if(isdigit(s[i])) curNum = curNum*10 + s[i] -'0';
10            else if(isspace(s[i])) continue;
11            else if(s[i] == '(')
12            {
13                 opS.push('(');
14                 opS.push('+');
15            }
16            else
17            {
18                 switch(opS.top())
19                 {
20                     case '*':
21                     case '/':
22                         curNum = opS.top()=='/'?numS.top()/curNum : numS.top()*curNum;
23                         opS.pop();
24                         numS.pop();
25                 }
26                 switch(s[i])
27                 {
28                     case ')':
29                         if('-'== opS.top()) curNum = -curNum;
30                        opS.pop();
31 
32                        while(opS.top()!='(') 
33                        {
34                            curNum += (opS.top()=='-')? -numS.top(): numS.top(); 
35                            opS.pop(); 
36                            numS.pop();
37                        }
38                        opS.pop(); // skip '('
39                        break;
40                     default: //+,-,*,/
41                         opS.push(s[i]);
42                         numS.push(curNum);
43                         curNum = 0;
44                 }
45            }
46        }
47        return curNum;
48     }
View Code

 

中缀表达式转逆波兰式

 1 class Solution {
 2 public:
 3     /**
 4      * @param expression: A string array
 5      * @return: The Reverse Polish notation of this expression
 6      */
 7     vector<string> convertToRPN(vector<string> &expression) {
 8         // write your code here
 9         vector<string>op;//符号栈
10         vector<string>num;//表达式结果栈
11         for(int i=0;i<expression.size();i++)//一遍扫描
12         {
13             if(expression[i]=="+" || expression[i]=="-")//处理加号、减号
14             {
15                 if(op.size()==0)
16                     op.push_back(expression[i]);
17                 else
18                 {
19                 while(op.size()!=0 && (op[op.size()-1]=="*" || op[op.size()-1]=="/" ||op[op.size()-1]=="+" || op[op.size()-1]=="-"))
20                 {
21                     string s=op.back();
22                     op.pop_back();
23                     num.push_back(s);
24                     
25                 } op.push_back(expression[i]);
26                 }
27                 if(op[op.size()-1]=="(")
28                 {
29                     op.push_back(expression[i]);
30                 }
31             }
32             else if(expression[i]=="*" || expression[i]=="/")//处理乘号、除号
33             {
34                  if(op.size()==0)
35                     op.push_back(expression[i]);
36                 else if(op[op.size()-1]=="*" || op[op.size()-1]=="/" )
37                 {
38                     string s=op.back();
39                     op.pop_back();
40                     num.push_back(s);
41                     op.push_back(expression[i]);
42                 }
43                  else if(op[op.size()-1]=="+" || op[op.size()-1]=="-")
44                 {
45                     op.push_back(expression[i]);
46                 }
47                  else if(op[op.size()-1]=="(")
48                 {
49                     op.push_back(expression[i]);
50                 }
51             }
52             else if(expression[i]=="(")//处理左括号
53             {
54                     op.push_back(expression[i]);
55             }
56             else if(expression[i]==")")//处理右括号
57             {
58                 while(op.back()!="(")
59                 {
60                     string s=op.back();
61                     op.pop_back();
62                     num.push_back(s);
63                  }
64                  op.pop_back();
65             }
66             else//运算数直接压入表达式结果栈
67             {
68                 num.push_back(expression[i]);
69             }
70         }
71         while(op.size()!=0)//符号栈仍有符号时,将其压入表达式结果栈
72         {
73             string s=op.back();
74             op.pop_back();
75             num.push_back(s);
76         }
77         return num;
78     }
79 };
View Code
  1 int symbol_priority(char &c)
  2 {
  3     if (c == '(')return 0;
  4     else if (c == '+' || c == '-')return 1;
  5     else if (c == '*' || c == '/')return 2;
  6     else if (c == ')')return 3;
  7     else return -1;
  8 }
  9 //判断优先级
 10 bool is_high(char &c)
 11 {
 12     if (symbol.empty())return true;
 13     else if (c == '(')return true;
 14     else if (symbol_priority(symbol.top())<symbol_priority(c))return true;
 15     else return false;
 16 }
 17 double calculator::operation(double & a, char c, double b)
 18 {
 19     if (c == '+')a += b;
 20     else if (c == '-')a -= b;
 21     else if (c == '*')a *= b;
 22     else if (c == '/')
 23     {
 24         if (abs(b) <= eps)return false;
 25         else return a /= b;
 26     }
 27     else return false;
 28     return true;
 29 }
 30 //中缀转后缀
 31 void calculator::do_suffix()
 32 {
 33     while (!expression.empty())
 34     {
 35         std::string str = expression.front();
 36         expression.pop();
 37         if (is_symbol(str[0]))
 38         {
 39             if (is_high(str[0]))
 40             {
 41                 if (str[0] == ')')
 42                 {
 43                     while (symbol.top() != '(')
 44                     {
 45                         std::string temp = "";
 46                         suffix.push(temp+=symbol.top());
 47                         symbol.pop();
 48                     }
 49                     symbol.pop();
 50                 }
 51                 else
 52                     symbol.push(str[0]);
 53             }
 54             else
 55             {
 56                 while (!symbol.empty())
 57                 {
 58                     if (is_high(str[0]))
 59                     {
 60                         break;
 61                     }
 62                     std::string temp = "";
 63                     suffix.push(temp+=symbol.top());
 64                     symbol.pop();
 65                 }
 66                 symbol.push(str[0]);
 67             }
 68         }
 69         else
 70         {
 71             suffix.push(str);
 72         }
 73     }
 74     while (!symbol.empty())
 75     {
 76         std::string temp = "";
 77         suffix.push(temp += symbol.top());
 78         symbol.pop();
 79     }
 80 }
 81 //计算
 82 bool calculator::count()
 83 {
 84     std::stack<double>number;
 85     while (!suffix.empty())
 86     {
 87         std::string temp = suffix.front();
 88         suffix.pop();
 89         if (!is_symbol(temp[0]))
 90         {
 91             number.push(atof(temp.c_str()));
 92         }
 93         else
 94         {
 95             double temp1 = number.top(); number.pop();
 96             double temp2 = number.top(); number.pop();
 97             if (!operation(temp2,temp[0],temp1))
 98             {
 99                 return false;
100             }
101             else
102             {
103                 number.push(temp2);
104             }
105         }
106     }
107     answer = number.top();
108     number.pop();
109     return true;
110 }
View Code

 

146. LRU Cache

 1 class LRUCache {
 2 public:
 3     list<pair<int, int>> storage;
 4     unordered_map<int, list<pair<int, int>>::iterator> mapping; 
 5     int capacity;
 6     
 7     LRUCache(int capacity) : capacity(capacity) {
 8         
 9     }
10     
11     int get(int key) {
12         if (mapping.find(key) == mapping.end())
13             return -1;
14         int val = mapping[key]->second;
15         storage.erase(mapping[key]);
16         storage.push_back({key, val});
17         mapping[key] = --storage.end();   
18         return val;
19     }
20     
21     void put(int key, int value) {
22         if (get(key) == -1) {
23             if (storage.size() == capacity) {
24                 mapping.erase(storage.begin()->first);
25                 storage.erase(storage.begin());
26             }
27             storage.push_back({key, value});
28             mapping[key] = --storage.end();
29         } else {
30             list<pair<int, int>>::iterator node = storage.end();
31             node--;
32             node->second = value;
33         }           
34     }
35 };
36 
37 /**
38  * Your LRUCache object will be instantiated and called as such:
39  * LRUCache obj = new LRUCache(capacity);
40  * int param_1 = obj.get(key);
41  * obj.put(key,value);
42  */
View Code

 

460. LFU Cache

 1 class LFUCache {
 2     int cap;
 3     int size;
 4     int minFreq;
 5     unordered_map<int, pair<int, int>> m; //key to {value,freq};
 6     unordered_map<int, list<int>::iterator> mIter; //key to list iterator;
 7     unordered_map<int, list<int>>  fm;  //freq to key list;
 8 public:
 9     LFUCache(int capacity) {
10         cap=capacity;
11         size=0;
12     }
13     
14     int get(int key) {
15         if(m.count(key)==0) return -1;
16         
17         fm[m[key].second].erase(mIter[key]);
18         m[key].second++;
19         fm[m[key].second].push_back(key);
20         mIter[key]=--fm[m[key].second].end();
21         
22         if(fm[minFreq].size()==0 ) 
23               minFreq++;
24         
25         return m[key].first;
26     }
27     
28    void set(int key, int value) {
29         if(cap<=0) return;
30         
31         int storedValue=get(key);
32         if(storedValue!=-1)
33         {
34             m[key].first=value;
35             return;
36         }
37         
38         if(size>=cap )
39         {
40             m.erase( fm[minFreq].front() );
41             mIter.erase( fm[minFreq].front() );
42             fm[minFreq].pop_front();
43             size--;
44         }
45         
46         m[key]={value, 1};
47         fm[1].push_back(key);
48         mIter[key]=--fm[1].end();
49         minFreq=1;
50         size++;
51     }
52 };
View Code
  1       Increasing frequencies
  2   ----------------------------->
  3 
  4 +------+    +---+    +---+    +---+
  5 | Head |----| 1 |----| 5 |----| 9 |  Frequencies
  6 +------+    +-+-+    +-+-+    +-+-+
  7               |        |        |
  8             +-+-+    +-+-+    +-+-+     |
  9             |2,3|    |4,3|    |6,2|     |
 10             +-+-+    +-+-+    +-+-+     | Most recent 
 11                        |        |       |
 12                      +-+-+    +-+-+     |
 13  key,value pairs     |1,2|    |7,9|     |
 14 
 15 
 16 
 17 class LFUCache
 18 {
 19  public:
 20   struct LRUNode
 21   {
 22     int freq;
 23     list<pair<int, int> > vals;
 24     LRUNode(int f = 0) : freq(f) { }
 25   };
 26 
 27   typedef list<LRUNode>::iterator iptr;
 28   typedef list<pair<int, int> >::iterator jptr;
 29 
 30   LFUCache(int capacity)
 31   {
 32     capacity_ = capacity;
 33   }
 34 
 35   int get(int key)
 36   {
 37     int val = -1;
 38     if (kv_.find(key) != kv_.end()) {
 39       kv_[key] = promote(key);
 40       val = kv_[key].second->second;
 41     }
 42     return val;
 43   }
 44 
 45   void set(int key, int value)
 46   {
 47     if (capacity_ <= 0) return;
 48     if (kv_.find(key) == kv_.end()) {
 49       if (kv_.size() == capacity_) evict();
 50       kv_[key] = insert(key, value);
 51     } else {
 52       kv_[key] = promote(key, value);
 53     }
 54   }
 55 
 56  private:
 57   pair<iptr, jptr> promote(int key, int val = -1)
 58   {
 59     iptr i; jptr j;
 60     tie(i, j) = kv_[key];
 61     iptr k = next(i);
 62 
 63     if (val < 0) val = j->second;
 64     int freq = i->freq + 1;
 65 
 66     i->vals.erase(j);
 67     if (i->vals.empty())
 68       cache_.erase(i);
 69 
 70     if (k == cache_.end() || k->freq != freq)
 71       i = cache_.insert(k, LRUNode(freq));
 72     else i = k;
 73     j = i->vals.insert(i->vals.end(), {key, val});
 74     return {i, j};
 75   }
 76 
 77   void evict()
 78   {
 79     iptr i = cache_.begin();
 80     jptr j = i->vals.begin();
 81     kv_.erase(j->first);
 82     i->vals.erase(j);
 83     if (i->vals.empty())
 84       cache_.erase(i);
 85   }
 86 
 87   pair<iptr, jptr> insert(int key, int val)
 88   {
 89     iptr i = cache_.begin();
 90     if (i == cache_.end() || i->freq != 1)
 91       i = cache_.insert(i, LRUNode(1));
 92     jptr j = i->vals.insert(i->vals.end(), {key, val});
 93     return {i, j};
 94   }
 95 
 96  private:
 97   list<LRUNode> cache_;
 98   int capacity_;
 99   unordered_map<int, pair<iptr, jptr> > kv_;
100 };
View Code
 1 class LFUCache {
 2 public:
 3     struct Node {
 4         int key; // key of the element.
 5         int val; // value of the ement.
 6         int fre; // usage frequency
 7         int timeStamp; // the latest time stamp when this element is accessed.
 8         Node(): key(-1), val(-1), timeStamp(-1), fre(0) {}
 9         Node(int k, int v, int ts): key(k), val(v), timeStamp(ts), fre(1) {}
10     };
11 
12     LFUCache(int capacity) {
13         Cap = capacity;
14         Node* dummy = new Node();
15         pq.push_back(dummy); // The pq start from pq[1].
16         ts = 0;
17     }
18     
19     int get(int key) {
20         if(!mp.count(key)) return -1;
21         int index = mp[key];
22         int val = pq[index]->val;
23     pq[index]->fre++;
24     pq[index]->timeStamp = ++ts;
25         sink(index);
26         return val;
27     }
28     
29     void set(int key, int value) {
30         if(Cap <= 0) return;
31     if(mp.count(key)) {
32        int index = mp[key];
33        pq[index]->val = value;
34        get(key);
35     }
36     else {
37         if(pq.size() - 1 == Cap) {
38             int oldKey = pq[1]->key;
39         mp.erase(oldKey);
40         Node* newnode = new Node(key, value, ++ts);
41         pq[1] = newnode;
42         mp[key] = 1;
43         sink(1);
44         }
45         else {
46             Node* newnode = new Node(key, value, ++ts);
47         pq.push_back(newnode);
48         mp[key] = pq.size() - 1;
49         swim(pq.size() - 1);
50         }
51     }
52     }
53     
54 private:
55     vector<Node*> pq; // A priority queue, with the least usage frequency and least recently used element at the top.
56     unordered_map<int, int> mp; // A mapping from the key of the element to its index in the priority queue.
57     int Cap; // Capcity of the cache
58     int ts; // time-stamp: indicate the time stamp of the latest operation of an element. According to the requirement of LFU cache, when we need to evict an element from the cache, but there are multiple elements with the same minimum frequency, then the least recently used element should be evicted.
59 
60     /*
61      * Recursively sink a node in priority queue. A node will be sinked, when its frequency is larger than any of its
62      * children nodes, or the node has the same frequency with a child, but it is recently updated. 
63      */
64     void sink(int index) {
65         int left = 2 * index, right = 2 * index + 1, target = index;
66         if(left < pq.size() && pq[left]->fre <= pq[target]->fre) // If the left child has the same frequency, we probably need to swap the parent node and the child node, because the parent node is recently accessed, and the left child node was accessed at an older time stamp.
67                target = left;
68             if(right < pq.size()) { 
69                 if(pq[right]->fre < pq[target]->fre || (pq[right]->fre == pq[target]->fre && pq[right]->timeStamp < pq[target]->timeStamp)) // If right child has the same frequency and an older time stamp, we must swap it.
70                      target = right;
71         }
72         if(target != index) {
73             myswap(target, index);
74                 sink(target);
75         }
76     }
77     
78     /*a
79      * Recursively swim a node in priority queue. A node will be swimmed, when its frequency is less than its
80      * parent node. If the node has the same frequency with its parent, it is not needed to be swimmed, because
81      * it is recently accessed.
82      */
83     void swim(int index) {
84         int par = index / 2;
85         while(par > 0 && pq[par]->fre > pq[index]->fre) {
86             myswap(par, index);
87         index = par;
88         par /= 2;
89         }
90     }
91 
92     void myswap(int id1, int id2) {
93         swap(pq[id1], pq[id2]);
94         mp[pq[id1]->key] = id1;
95         mp[pq[id2]->key] = id2;
96     }
97 };
View Code

 

split string in C

#include <string>
#include <sstream>
#include <vector>
#include <iterator>

template<typename Out>
void split(const std::string &s, char delim, Out result) {
    std::stringstream ss(s);
    std::string item;
    while (std::getline(ss, item, delim)) {
        *(result++) = item;
    }
}

std::vector<std::string> split(const std::string &s, char delim) {
    std::vector<std::string> elems;
    split(s, delim, std::back_inserter(elems));
    return elems;
}

// std::vector<std::string> x = split("one:two::three", ':');
// "one", "two", "", "three"
View Code

 

quicksort

 1 template<typename T>
 2 void qsort(T arr[], int l, int r) {
 3     /*
 4      * 功能:对数组升序快排,递归实现
 5      * 参数:arr:带排序数组,l:数组首元素下标,r:数组末元素下标
 6      * 返回值:无
 7      */
 8     
 9     if (l >= r) return ;
10 
11     int i = l, j = r;
12 
13     T pivot = arr[l];  // 通常取第一个数为基准
14 
15     while (i < j) { // i,j 相遇即退出循环
16         while (i < j && arr[j] >= pivot) j--;
17         arr[i] = arr[j];    // 从右向左扫描,将比基准小的数填到左边
18         while (i < j && arr[i] <= pivot) i++;
19         arr[j] = arr[i];    //  从左向右扫描,将比基准大的数填到右边
20     }
21 
22     arr[i] = pivot; // 将 基准数 填回
23 
24     qsort(arr, l, i - 1);    // 以基准数为界左右分治
25     qsort(arr, i + 1, r);
26 }
posted @ 2018-02-03 15:57  我在地狱  阅读(868)  评论(0编辑  收藏  举报