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. 关于dbw 与dbm 的计算

    一分贝(dB)表示单元信号强度的相对差异.其比率的基础对数为10,,如dB = 10 x Log10 (P1/P2). 基础10对数规则: Log10 (AxB) = Log10(A) + Log10 ...

  2. Jmeter接口测试(五)变量及参数化

    在请求过程中,有时我们需要在请求中设置一些变量来测试不同的场景. 提示:在调试请求过程中,无关的请求可以暂时禁用掉,选择某个暂时不用的请求,右键--禁用 Jmeter 支持以下类型变量:所有类型的变量 ...

  3. CSS清浮动办法

    骨灰级解决办法: .clear{clear:both;height:0;overflow:hidden;} 上诉办法是在需要清除浮动的地方加个div.clear或者br.clear,我们知道这样能解决 ...

  4. 关于jsp中引用css外部样式无效时的处理方法

    今天做项目遇到的一个小问题,如下所示: <link href="./bootstrap/css/bootstrap.min.css" rel="stylesheet ...

  5. Linux系统下安装jdk1.8

    JDK安装分为两种方式  一种是解压tar.gz配置安装, 一种是rpm安装,我这里是tar.gz安装方式 一.首先在oracle官方网下载jdk,网址如下:http://www.oracle.com ...

  6. Flexbox + js实现滑动拼图游戏

    滑动拼图就是把一张图片分成几等份,打乱顺序(下图),然后通过滑动拼凑成一张完整的图片. 要实现一个拼图游戏,需要考虑怎样随机的打乱顺序,怎样交换两张图片的位置,等等.但是,使用了Flexbox布局以后 ...

  7. sprint2(第四天)

    由于最近网络不行,更新的代码push不上Github,组员之间又不能clone得到最新的项目,所以这几天都没有更新到Github 燃尽图

  8. js中模拟a标签的点击事件

    var a = document.createElement('a'); a.target = "_blank"; a.href = "personal"; a ...

  9. 《Spring2之站立会议2》

    <Spring2之站立会议2> 昨天,模仿着资料把客户端和服务器端的代码写了一下: 今天,继续找本机的端口号和逐步深入理解代码含义: 遇到的问题,在理解时,对一些知识理解还是比较朦胧,一知 ...

  10. Fast Packet Processing - A Survey

    笔记是边读边写的旁注,比较乱,没有整理就丢上来了. 可以说不仅要说fast packet process servey,也同时是一篇packet process的综述了.packet processi ...