LeetCode中级算法之其他
两整数之和
Question:
不使用运算符 + 和 - ,计算两整数 a 、b 之和。
示例 1:
输入: a = 1, b = 2
输出: 3
示例 2:
输入: a = -2, b = 3
输出: 1
Solution:
int getSum(int a, int b) {
if(b == 0) return a;
int a1 = a ^ b;
int b1 = (unsigned int)(a & b) << 1;
return getSum(a1,b1);
}
逆波兰表达式求值
Question:
根据逆波兰表示法,求表达式的值。
有效的运算符包括 +, -, *, / 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。
说明:
整数除法只保留整数部分。
给定逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。
示例 1:
输入: ["2", "1", "+", "3", "*"]
输出: 9
解释: ((2 + 1) * 3) = 9
示例 2:
输入: ["4", "13", "5", "/", "+"]
输出: 6
解释: (4 + (13 / 5)) = 6
示例 3:
输入: ["10", "6", "9", "3", "+", "-11", "*", "/", "*", "17", "+", "5", "+"]
输出: 22
解释:
((10 * (6 / ((9 + 3) * -11))) + 17) + 5
= ((10 * (6 / (12 * -11))) + 17) + 5
= ((10 * (6 / -132)) + 17) + 5
= ((10 * 0) + 17) + 5
= (0 + 17) + 5
= 17 + 5
= 22
Solution:
建立一个栈,每次遇到数字就入栈,遇到运算符就取出栈顶的两个数,并将运算结果存入栈中,最终栈中剩下的数就是结果:
int evalRPN(vector<string>& tokens) {
stack <int> suzy;
if(tokens.empty()) return 0;
for(int i = 0; i < tokens.size(); i++)
{
if(tokens[i] == "+")
{
int a = suzy.top();
suzy.pop();
int b = suzy.top();
suzy.pop();
suzy.push(a + b);
}
else if(tokens[i] == "-")
{
int a = suzy.top();
suzy.pop();
int b = suzy.top();
suzy.pop();
suzy.push(b - a);
}
else if(tokens[i] == "*")
{
int a = suzy.top();
suzy.pop();
int b = suzy.top();
suzy.pop();
suzy.push(a * b);
}
else if(tokens[i] == "/")
{
int a = suzy.top();
suzy.pop();
int b = suzy.top();
suzy.pop();
suzy.push(b / a);
}
else
{
int num = 0;
int j = 0, flag = 1;
if(tokens[i][j] == '-')
{
flag = 0;
j++;
}
for(; j < tokens[i].length(); j++)
{
num *= 10;
num += (tokens[i][j] - '0');
}
if(!flag) num = -num;
suzy.push(num);
}
}
return suzy.top();
}
求众数
Question:
给定一个大小为 n 的数组,找到其中的众数。众数是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在众数。
示例 1:
输入: [3,2,3]
输出: 3
示例 2:
输入: [2,2,1,1,1,2,2]
输出: 2
Solution:
建立hashmap来统计出现次数即可:
int majorityElement(vector<int>& nums) {
map <int,int> m;
map<int,int>::iterator it;
for(int i = 0; i < nums.size(); i++)
{
if(m[nums[i]]) m[nums[i]]++;
else m[nums[i]] = 1;
}
it = m.begin();
int max = it -> second, rec = it -> first;
for(; it != m.end(); it++)
{
if(it -> second > max)
{
max = it -> second;
rec = it -> first;
}
}
return rec;
}
同时也在网上看了其他人的方法,觉得还是很值得借鉴的,特贴在下面:
摩尔投票算法
算法在局部变量中定义一个序列元素(value)和一个计数器(count),初始化的情况下计数器为0.
算法依次扫描序列中的元素,当处理元素x的时候,如果计数器为0,那么将x赋值给value,然后将计数器count设置为1,如果计数器不为0,那么将序列元素value和x比较,如果相等,那么计数器加1,如果不等,那么计数器减1。
最后存储的序列元素(value),就是这个序列中最多的元素。如果不确定是否存储的元素m是最多的元素,还可以进行第二遍扫描判断是否为最多的元素。
转自链接:https://www.jianshu.com/p/0abb24b4dd38
Task Scheduler
给定一个用字符数组表示的 CPU 需要执行的任务列表。其中包含使用大写的 A - Z 字母表示的26 种不同种类的任务。任务可以以任意顺序执行,并且每个任务都可以在 1 个单位时间内执行完。CPU 在任何一个单位时间内都可以执行一个任务,或者在待命状态。
然而,两个相同种类的任务之间必须有长度为 n 的冷却时间,因此至少有连续 n 个单位时间内 CPU 在执行不同的任务,或者在待命状态。
你需要计算完成所有任务所需要的最短时间。
示例 1:
输入: tasks = ["A","A","A","B","B","B"], n = 2
输出: 8
执行顺序: A -> B -> (待命) -> A -> B -> (待命) -> A -> B.
注:
任务的总个数为 [1, 10000]。
n 的取值范围为 [0, 100]。
Solution:
这道题我刚开始用操作系统调度的方法做的,发现达不到最优,然后上网参考了大神的思路,才发现这种题还是要找规律的,找出出现次数最多的任务,最终的调度时间正好就是这个任务完成的时间和任务序列长度之间的最大值,具体还是直接去看原贴:
写在后面
这几道题除了最后一题都还可以,最后一题是没有考虑到出题者的初衷,可能是刚刚上完操作系统把上来就直接调度),通过做题感觉自己的手感上来了,但是思路还跟不上,不过现在至少能做到有思路就有代码,这也是进步吧!继续加油~