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. cpp-variable-lifetime

    #include <cstdio> #include <iostream> using namespace std; class TmpClass; void FuncScop ...

  2. 【坚持】Selenium+Python学习之从读懂代码开始 DAY5

    2018/05/22 函数作为返回值 [来源:廖雪峰的官方网站](https://www.liaoxuefeng.com/) #No.1 def lazy_sum(*args): def sum(): ...

  3. MPVUE多环境定义后台URL

    小程序选定了mpvue作为开发框架,搭建开发环境和构建环境.自从用了Travis和Jenkins之后,再也回不到手工构建的时代了. 目的-自动构建 web项目中,自从前后台分离的结构形成,就形成了一个 ...

  4. Netty源码分析第8章(高性能工具类FastThreadLocal和Recycler)---->第1节: FastThreadLocal的使用和创建

    Netty源码分析第八章: 高性能工具类FastThreadLocal和Recycler 概述: FastThreadLocal我们在剖析堆外内存分配的时候简单介绍过, 它类似于JDK的ThreadL ...

  5. yocto-sumo源码解析(八): ProcessServer

    从前面章节的论述中,我们知道BitBakeServer实际上是一个ProcessServer,什么是ProcessServer不可不了解. 1. 类的声明: 首先这是一个python的多进程包里面的进 ...

  6. http跳转https方法:百度云如何让http自动跳转到https【免费SSL证书使用FAQ】

    之前的一篇文章已经给大家提供了免费SSL证书的申请方法,这一篇文章是告诉大家在使用免费的SSL证书时可能会遇到的问题[怎么让http自动跳转到https以及http与https同时使用]的解决方法. ...

  7. 【Docker】第四篇 Docker仓库管理

    一.仓库概述 仓库(Repository):Docker仓库主要用于镜像的存储,它是镜像分发.部署的关键.仓库分为公共仓库和私有仓库. 注册服务器(Registry)和仓库区别:注册服务器上往往存放着 ...

  8. kubeadm 线上集群部署(一) 外部 ETCD 集群搭建

      IP Hostname   192.168.1.23 k8s-etcd-01 etcd集群节点,默认关于ETCD所有操作均在此节点上操作 192.168.1.24 k8s-etcd-02 etcd ...

  9. 【视频编解码·学习笔记】13. 提取PPS信息程序

    PPS结构解析 与之前解析SPS方式类似 一.定义PPS类: 在3.NAL Unit目录下,新建PicParamSet.cpp和PicParamSet.h,在这两个文件中写入类的定义和函数实现. 类定 ...

  10. 搬运_maven打包

    参考文章 利用Maven插件将依赖包.jar/war包及配置文件输出到指定目录 <build> <plugins> <plugin> <groupId> ...