43. Multiply Strings

高精度非负整数的乘法。

 string multiply(string num1, string num2) {
string sum(num1.size() + num2.size(), ''); for (int i = num1.size() - ; <= i; --i) {
int carry = ;
for (int j = num2.size() - ; <= j; --j) {
int tmp = (sum[i + j + ] - '') + (num1[i] - '') * (num2[j] - '') + carry;
sum[i + j + ] = tmp % + '';
carry = tmp / ;
}
sum[i] += carry;
} size_t startpos = sum.find_first_not_of("");
if (string::npos != startpos) {
return sum.substr(startpos);
}
return "";
}
     string multiply(string num1, string num2) {
int i, j;
int m = num1.size(), n = num2.size();
// max (m + n) digits
vector<int> product(m + n, );
string result; // reverse for ease of calc
reverse(num1.begin(), num1.end());
reverse(num2.begin(), num2.end()); // digit i * digit j contributes to digit i + j
for (i = ; i < m; i++) {
for (j = ; j < n; j++) {
product[i + j] += (num1[i] - '') * (num2[j] - '');
product[i + j + ] += product[i + j] / ;
product[i + j] %= ;
}
} // remove leading 0; keep last 0 if all 0
for (i = m + n - ; i > && == product[i]; i--); for (; i >= ; i--)
result += to_string(product[i]); return result;
}

224. Basic Calculator

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

     int calculate(string s) {
stack <int> nums, ops;
int num = ;
int rst = ;
int sign = ;
for (char c : s) {
if (isdigit(c)) {
num = num * + c - '';
}
else {
rst += sign * num;
num = ;
if (c == '+') sign = ;
if (c == '-') sign = -;
if (c == '(') {
nums.push(rst);
ops.push(sign);
rst = ;
sign = ;
}
if (c == ')' && ops.size()) {
rst = ops.top() * rst + nums.top();
ops.pop(); nums.pop();
}
}
}
rst += sign * num;
return rst;
}
 class Solution {
public:
int calculate(string s) {
int n = s.size();
stack<int> s1;
stack<char> s2;
string v;
for(int i = n - ; i >= ; i--){
if(s[i] == ')' || s[i] == '+' || s[i] == '-') s2.push(s[i]);
else if(s[i] >= '' && s[i] <= ''){
v = s[i] + v;
if(i == || s[i - ] < '' || s[i - ] > ''){
s1.push(stoi(v));
v = "";
}
} else if(s[i] == '('){
while(s2.top() != ')') cal(s1, s2);
s2.pop();
}
}
while(!s2.empty()) cal(s1, s2);
return s1.top();
} void cal(stack<int> &s1, stack<char> &s2){
int v1 = s1.top(); s1.pop();
int v2 = s1.top(); s1.pop();
char c = s2.top(); s2.pop();
if(c == '+') s1.push(v1 + v2);
if(c == '-') s1.push(v1 - v2);
}
};

227. Basic Calculator II

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

 int calculate(string s) {
stack<char> opS;
stack<int> numS;
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
opS.push('+'); // sign for the first operand int i, curNum, len = s.size(), res =;
for(i=,curNum=; i<len; ++i)
{
if(isdigit(s[i])) curNum = curNum* + s[i] -''; // digit, recover the oprand
else if(isspace(s[i])) continue; // skip the space
else
{
switch(opS.top())
{
case '*': // if the last operator is * / , do calculation
case '/':
curNum = opS.top()=='/'?numS.top()/curNum : numS.top()*curNum;
opS.pop();
numS.pop();
}
numS.push(curNum); /
curNum = ;
opS.push(s[i]);
}
}
opS.pop(); // skip the ")"
while(!opS.empty()) {res += (opS.top()=='-')? -numS.top(): numS.top(); opS.pop(); numS.pop();}
return res;
}

附含括号的代码:

     int calculate(string s) {
stack<char> opS;
stack<int> numS;
s = '(' + s + ')'; int i, curNum = , len = s.size();
for(i=; i<len; ++i)
{
if(isdigit(s[i])) curNum = curNum* + s[i] -'';
else if(isspace(s[i])) continue;
else if(s[i] == '(')
{
opS.push('(');
opS.push('+');
}
else
{
switch(opS.top())
{
case '*':
case '/':
curNum = opS.top()=='/'?numS.top()/curNum : numS.top()*curNum;
opS.pop();
numS.pop();
}
switch(s[i])
{
case ')':
if('-'== opS.top()) curNum = -curNum;
opS.pop(); while(opS.top()!='(')
{
curNum += (opS.top()=='-')? -numS.top(): numS.top();
opS.pop();
numS.pop();
}
opS.pop(); // skip '('
break;
default: //+,-,*,/
opS.push(s[i]);
numS.push(curNum);
curNum = ;
}
}
}
return curNum;
}

中缀表达式转逆波兰式

 class Solution {
public:
/**
* @param expression: A string array
* @return: The Reverse Polish notation of this expression
*/
vector<string> convertToRPN(vector<string> &expression) {
// write your code here
vector<string>op;//符号栈
vector<string>num;//表达式结果栈
for(int i=;i<expression.size();i++)//一遍扫描
{
if(expression[i]=="+" || expression[i]=="-")//处理加号、减号
{
if(op.size()==)
op.push_back(expression[i]);
else
{
while(op.size()!= && (op[op.size()-]=="*" || op[op.size()-]=="/" ||op[op.size()-]=="+" || op[op.size()-]=="-"))
{
string s=op.back();
op.pop_back();
num.push_back(s); } op.push_back(expression[i]);
}
if(op[op.size()-]=="(")
{
op.push_back(expression[i]);
}
}
else if(expression[i]=="*" || expression[i]=="/")//处理乘号、除号
{
if(op.size()==)
op.push_back(expression[i]);
else if(op[op.size()-]=="*" || op[op.size()-]=="/" )
{
string s=op.back();
op.pop_back();
num.push_back(s);
op.push_back(expression[i]);
}
else if(op[op.size()-]=="+" || op[op.size()-]=="-")
{
op.push_back(expression[i]);
}
else if(op[op.size()-]=="(")
{
op.push_back(expression[i]);
}
}
else if(expression[i]=="(")//处理左括号
{
op.push_back(expression[i]);
}
else if(expression[i]==")")//处理右括号
{
while(op.back()!="(")
{
string s=op.back();
op.pop_back();
num.push_back(s);
}
op.pop_back();
}
else//运算数直接压入表达式结果栈
{
num.push_back(expression[i]);
}
}
while(op.size()!=)//符号栈仍有符号时,将其压入表达式结果栈
{
string s=op.back();
op.pop_back();
num.push_back(s);
}
return num;
}
};
 int symbol_priority(char &c)
{
if (c == '(')return ;
else if (c == '+' || c == '-')return ;
else if (c == '*' || c == '/')return ;
else if (c == ')')return ;
else return -;
}
//判断优先级
bool is_high(char &c)
{
if (symbol.empty())return true;
else if (c == '(')return true;
else if (symbol_priority(symbol.top())<symbol_priority(c))return true;
else return false;
}
double calculator::operation(double & a, char c, double b)
{
if (c == '+')a += b;
else if (c == '-')a -= b;
else if (c == '*')a *= b;
else if (c == '/')
{
if (abs(b) <= eps)return false;
else return a /= b;
}
else return false;
return true;
}
//中缀转后缀
void calculator::do_suffix()
{
while (!expression.empty())
{
std::string str = expression.front();
expression.pop();
if (is_symbol(str[]))
{
if (is_high(str[]))
{
if (str[] == ')')
{
while (symbol.top() != '(')
{
std::string temp = "";
suffix.push(temp+=symbol.top());
symbol.pop();
}
symbol.pop();
}
else
symbol.push(str[]);
}
else
{
while (!symbol.empty())
{
if (is_high(str[]))
{
break;
}
std::string temp = "";
suffix.push(temp+=symbol.top());
symbol.pop();
}
symbol.push(str[]);
}
}
else
{
suffix.push(str);
}
}
while (!symbol.empty())
{
std::string temp = "";
suffix.push(temp += symbol.top());
symbol.pop();
}
}
//计算
bool calculator::count()
{
std::stack<double>number;
while (!suffix.empty())
{
std::string temp = suffix.front();
suffix.pop();
if (!is_symbol(temp[]))
{
number.push(atof(temp.c_str()));
}
else
{
double temp1 = number.top(); number.pop();
double temp2 = number.top(); number.pop();
if (!operation(temp2,temp[],temp1))
{
return false;
}
else
{
number.push(temp2);
}
}
}
answer = number.top();
number.pop();
return true;
}

146. LRU Cache

 class LRUCache {
public:
list<pair<int, int>> storage;
unordered_map<int, list<pair<int, int>>::iterator> mapping;
int capacity; LRUCache(int capacity) : capacity(capacity) { } int get(int key) {
if (mapping.find(key) == mapping.end())
return -;
int val = mapping[key]->second;
storage.erase(mapping[key]);
storage.push_back({key, val});
mapping[key] = --storage.end();
return val;
} void put(int key, int value) {
if (get(key) == -) {
if (storage.size() == capacity) {
mapping.erase(storage.begin()->first);
storage.erase(storage.begin());
}
storage.push_back({key, value});
mapping[key] = --storage.end();
} else {
list<pair<int, int>>::iterator node = storage.end();
node--;
node->second = value;
}
}
}; /**
* Your LRUCache object will be instantiated and called as such:
* LRUCache obj = new LRUCache(capacity);
* int param_1 = obj.get(key);
* obj.put(key,value);
*/

460. LFU Cache

 class LFUCache {
int cap;
int size;
int minFreq;
unordered_map<int, pair<int, int>> m; //key to {value,freq};
unordered_map<int, list<int>::iterator> mIter; //key to list iterator;
unordered_map<int, list<int>> fm; //freq to key list;
public:
LFUCache(int capacity) {
cap=capacity;
size=;
} int get(int key) {
if(m.count(key)==) return -; fm[m[key].second].erase(mIter[key]);
m[key].second++;
fm[m[key].second].push_back(key);
mIter[key]=--fm[m[key].second].end(); if(fm[minFreq].size()== )
minFreq++; return m[key].first;
} void set(int key, int value) {
if(cap<=) return; int storedValue=get(key);
if(storedValue!=-)
{
m[key].first=value;
return;
} if(size>=cap )
{
m.erase( fm[minFreq].front() );
mIter.erase( fm[minFreq].front() );
fm[minFreq].pop_front();
size--;
} m[key]={value, };
fm[].push_back(key);
mIter[key]=--fm[].end();
minFreq=;
size++;
}
};
       Increasing frequencies
-----------------------------> +------+ +---+ +---+ +---+
| Head |----| |----| |----| | Frequencies
+------+ +-+-+ +-+-+ +-+-+
| | |
+-+-+ +-+-+ +-+-+ |
|,| |,| |,| |
+-+-+ +-+-+ +-+-+ | Most recent
| | |
+-+-+ +-+-+ |
key,value pairs |,| |,| | class LFUCache
{
public:
struct LRUNode
{
int freq;
list<pair<int, int> > vals;
LRUNode(int f = ) : freq(f) { }
}; typedef list<LRUNode>::iterator iptr;
typedef list<pair<int, int> >::iterator jptr; LFUCache(int capacity)
{
capacity_ = capacity;
} int get(int key)
{
int val = -;
if (kv_.find(key) != kv_.end()) {
kv_[key] = promote(key);
val = kv_[key].second->second;
}
return val;
} void set(int key, int value)
{
if (capacity_ <= ) return;
if (kv_.find(key) == kv_.end()) {
if (kv_.size() == capacity_) evict();
kv_[key] = insert(key, value);
} else {
kv_[key] = promote(key, value);
}
} private:
pair<iptr, jptr> promote(int key, int val = -)
{
iptr i; jptr j;
tie(i, j) = kv_[key];
iptr k = next(i); if (val < ) val = j->second;
int freq = i->freq + ; i->vals.erase(j);
if (i->vals.empty())
cache_.erase(i); if (k == cache_.end() || k->freq != freq)
i = cache_.insert(k, LRUNode(freq));
else i = k;
j = i->vals.insert(i->vals.end(), {key, val});
return {i, j};
} void evict()
{
iptr i = cache_.begin();
jptr j = i->vals.begin();
kv_.erase(j->first);
i->vals.erase(j);
if (i->vals.empty())
cache_.erase(i);
} pair<iptr, jptr> insert(int key, int val)
{
iptr i = cache_.begin();
if (i == cache_.end() || i->freq != )
i = cache_.insert(i, LRUNode());
jptr j = i->vals.insert(i->vals.end(), {key, val});
return {i, j};
} private:
list<LRUNode> cache_;
int capacity_;
unordered_map<int, pair<iptr, jptr> > kv_;
};
 class LFUCache {
public:
struct Node {
int key; // key of the element.
int val; // value of the ement.
int fre; // usage frequency
int timeStamp; // the latest time stamp when this element is accessed.
Node(): key(-), val(-), timeStamp(-), fre() {}
Node(int k, int v, int ts): key(k), val(v), timeStamp(ts), fre() {}
}; LFUCache(int capacity) {
Cap = capacity;
Node* dummy = new Node();
pq.push_back(dummy); // The pq start from pq[1].
ts = ;
} int get(int key) {
if(!mp.count(key)) return -;
int index = mp[key];
int val = pq[index]->val;
pq[index]->fre++;
pq[index]->timeStamp = ++ts;
sink(index);
return val;
} void set(int key, int value) {
if(Cap <= ) return;
if(mp.count(key)) {
int index = mp[key];
pq[index]->val = value;
get(key);
}
else {
if(pq.size() - == Cap) {
int oldKey = pq[]->key;
mp.erase(oldKey);
Node* newnode = new Node(key, value, ++ts);
pq[] = newnode;
mp[key] = ;
sink();
}
else {
Node* newnode = new Node(key, value, ++ts);
pq.push_back(newnode);
mp[key] = pq.size() - ;
swim(pq.size() - );
}
}
} private:
vector<Node*> pq; // A priority queue, with the least usage frequency and least recently used element at the top.
unordered_map<int, int> mp; // A mapping from the key of the element to its index in the priority queue.
int Cap; // Capcity of the cache
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. /*
* Recursively sink a node in priority queue. A node will be sinked, when its frequency is larger than any of its
* children nodes, or the node has the same frequency with a child, but it is recently updated.
*/
void sink(int index) {
int left = * index, right = * index + , target = index;
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.
target = left;
if(right < pq.size()) {
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.
target = right;
}
if(target != index) {
myswap(target, index);
sink(target);
}
} /*a
* Recursively swim a node in priority queue. A node will be swimmed, when its frequency is less than its
* parent node. If the node has the same frequency with its parent, it is not needed to be swimmed, because
* it is recently accessed.
*/
void swim(int index) {
int par = index / ;
while(par > && pq[par]->fre > pq[index]->fre) {
myswap(par, index);
index = par;
par /= ;
}
} void myswap(int id1, int id2) {
swap(pq[id1], pq[id2]);
mp[pq[id1]->key] = id1;
mp[pq[id2]->key] = id2;
}
};

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"

quicksort

int PartSort(int* array, int left, int right) {
int& key = array[right];
while(left < right) {
while(left < right && array[left] <= key)
++left;
while(left < right && array[right] >= key)
--right;
swap(array[left], array[right]);
}
swap(array[left], key);
return left;
}

Leetcode模拟题篇的更多相关文章

  1. LeetCode刷题专栏第一篇--思维导图&时间安排

    昨天是元宵节,过完元宵节相当于这个年正式过完了.不知道大家有没有投入继续投入紧张的学习工作中.年前我想开一个Leetcode刷题专栏,于是发了一个投票想了解大家的需求征集意见.投票于2019年2月1日 ...

  2. LeetCode刷题总结-数组篇(上)

    数组是算法中最常用的一种数据结构,也是面试中最常考的考点.在LeetCode题库中,标记为数组类型的习题到目前为止,已累计到了202题.然而,这202道习题并不是每道题只标记为数组一个考点,大部分习题 ...

  3. LeetCode刷题总结-数组篇(中)

    本文接着上一篇文章<LeetCode刷题总结-数组篇(上)>,继续讲第二个常考问题:矩阵问题. 矩阵也可以称为二维数组.在LeetCode相关习题中,作者总结发现主要考点有:矩阵元素的遍历 ...

  4. LeetCode刷题总结-数组篇(下)

    本期讲O(n)类型问题,共14题.3道简单题,9道中等题,2道困难题.数组篇共归纳总结了50题,本篇是数组篇的最后一篇.其他三个篇章可参考: LeetCode刷题总结-数组篇(上),子数组问题(共17 ...

  5. LeetCode刷题总结-树篇(下)

    本文讲解有关树的习题中子树问题和新概念定义问题,也是有关树习题的最后一篇总结.前两篇请参考: LeetCode刷题总结-树篇(上) LeetCode刷题总结-树篇(中) 本文共收录9道题,7道中等题, ...

  6. LeetCode刷题总结-树篇(中)

    本篇接着<LeetCode刷题总结-树篇(上)>,讲解有关树的类型相关考点的习题,本期共收录17道题,1道简单题,10道中等题,6道困难题. 在LeetCode题库中,考察到的不同种类的树 ...

  7. LeetCode刷题总结-树篇(上)

          引子:刷题的过程可能是枯燥的,但程序员们的日常确不乏趣味.分享一则LeetCode上名为<打家劫舍 |||>题目的评论: 如有兴趣可以从此题为起点,去LeetCode开启刷题之 ...

  8. C#LeetCode刷题-贪心算法

    贪心算法篇 # 题名 刷题 通过率 难度 44 通配符匹配   17.8% 困难 45 跳跃游戏 II   25.5% 困难 55 跳跃游戏   30.6% 中等 122 买卖股票的最佳时机 II C ...

  9. Leetcode刷题笔记(双指针)

    1.何为双指针 双指针主要用来遍历数组,两个指针指向不同的元素,从而协同完成任务.我们也可以类比这个概念,推广到多个数组的多个指针. 若两个指针指向同一数组,遍历方向相同且不会相交,可以称之为滑动窗口 ...

随机推荐

  1. 人工智能AI芯片与Maker创意接轨 (上)

    近几年来人工智能(Artificial Intelligence, AI)喴的震天价响,吃也要AI,穿也要AI,连上个厕所也要来个AI智能健康分析,生活周遭食衣住行育乐几乎无处不AI,彷佛已经来到科幻 ...

  2. undefined和“undefined”

    说实话,它们之间的区别挺明显的,我们一般认为undefined是JavaScript提供的一个“关键字”,而“undefined”却是一个字符串,只是引号的内容和undefined一样. undefi ...

  3. Python-RabbitMQ(简单发送模型)

    RabbitMQ需要 erlang 和pika 1.RabbitMQ和erlang版本必须匹配,否则就报没有进程错误 2.RabbitMQ的erlang.cookie和windows下的erlang. ...

  4. Annotation 使用备忘2

    title: Annotation 使用备忘 date: 2018-01-02 20:48:43 tags: [Annotation] categories: [Programming,Java] - ...

  5. mongodb基本使用(一)

    1.启动.停止和重启mongodb服务 brew services start mongodb  ---启动 brew services stop mongodb --停止 brew services ...

  6. 阿里云oracle启动失败

    1.监听启动失败: 将$ORACLE_HOME/network/admin 中的listener.ora中的主机名改为localhost 2.sqlplus中startup启动失败 ,出现ORA-00 ...

  7. BugPhobia准备篇章:Beta阶段前后端接口文档

    0x00:序言 Two strangers fell in love, Only one knows it wasn’t by chance. To the searching tags, you m ...

  8. 在Windows下制作静态库和动态库

    一:静态库的创建 VC++6.0中new一个的为win32 static library工程,之后有二个选项.根据需求选吧. 具体的类或者函数的添加过程和标准的工程一样,直接创建新的类或者添加新 的. ...

  9. Git管理分支

    管理分支:git branch 直至现在为止,我们的项目版本库一直都是只有一个分支 master.在 git 版本库中创建分支的成本几乎为零,所以,不必吝啬多创建几个分支.下面列举一些常见的分支策略, ...

  10. b5

    吴晓晖(组长) 过去两天完成了哪些任务 完善推荐算法 展示GitHub当日代码/文档签入记录 接下来的计划 推荐算法 还剩下哪些任务 组员:刘帅珍 过去两天完成了哪些任务: 修改原型,整理背景 明日计 ...