题目描述
在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
思路:这题较好的思路有两个,一个是最容易想到的nlog,枚举行,二分列。另一种就是从左下角逐步枚举,如果大于目标值就向上走,小于目标值就向右走,这样每次2选1最多走n步,复杂度O(n),之所以不能从常规的左上,因为左上都是行列递增的,无法抉择,左下或者右上行列走势不同,可以唯一确定路径
代码:
class Solution {
public:
bool Find(int target, vector<vector<int> > array) {
int tx = array.size()-1;
int n = array[0].size();
int ty = 0;
while(1)
{
if(tx < 0 || ty >= n) break;
if(array[tx][ty] > target) tx--;
else if(array[tx][ty] < target) ty++;
else
{
return true;
break;
}
}
return false;
}
};
题目描述
请实现一个函数,将一个字符串中的空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
没什么好说的,注意他题目其实让你把str变成最后的答案。。 也可以从前往后数几个空格,然后从后往前替换,每个字符都要往后移动2*cnt个位置,cnt是这个字符前面的空格数。
void replaceSpace(char *str,int length)
{
char tmp[1000];
for(int i = 0; i < length; i++)
tmp[i] = str[i];
tmp[length] = '\0';
int index = 0;
for(int i = 0; i < length; i++)
{
if(tmp[i] == ' ')
str[index++] = '%', str[index++] = '2', str[index++] = '0';
else
str[index++] = tmp[i];
// cout << str << "&&&&" << tmp <<endl;
}
str[index] = '\0';
}
题目描述
求1+2+3+...+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。
递归+短路特性
int Sum_Solution(int n) {
int ans = n;
ans && (ans = ans + Sum_Solution(n-1));
return ans;
}
题目描述
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
原来只能跳1个2个其实就是个简单dp递推式,这个思路还蛮多的
思路1:一眼dp优化,前缀优化下就好了
思路2:每个台阶都有跳与不跳两种情况(除了最后一个台阶),最后一个台阶必须跳。所以共用2^(n-1)中情况
思路3:f(n)=f(n-1)+f(n-2)+...+f(1),因为f(n-1)=f(n-2)+f(n-3)+...+f(1),所以f(n)=2*f(n-1)
代码:
int jumpFloorII(int number)
{
int sum = 0;
int dp[500];
dp[0] = 1;
dp[1] = 1;
dp[2] = 2;
sum = 3;
for(int i = 3; i <= number; i++)
{
dp[i] = sum + 1;
sum += dp[i];
}
return dp[number];
}
题目描述
我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
思路:一看这道题让我想到了当年做匹配问题的时候233 画图看看,发现这个跟青蛙只能跳1,2个格子题目一样,dp[i]代表i之前有多少种放法,你要么竖着放,占一列,要么横着放占两列(放两个) 转移方程一目了然
int rectCover(int number) {
int dp[500];
dp[1] = 1; dp[2] = 2;
for(int i = 3; i <= number; i++)
dp[i] = dp[i-1] + dp[i-2];
return dp[number];
}
题目描述
给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
思路:面试题可能不会考你各种算法,算法的变形,都会考你细节,考一些坑,比如这个。。。没告诉你ex的正负号。。你要自己去分类,剩下的就是快速幂了
double Power(double base, int exponent) {
double ans = 1, tmp = 1;
int a = abs(exponent);
while(a)
{
if(a & 1) ans = ans * base;
a >>= 1;
base *= base;
}
return exponent < 0 ? 1/ans : ans;
}
题目描述
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
思路:也算是一个经典题了,最后记得跑一下全部看看他是不是超过了一半,因为最后剩下的不是众数,就是最后的数
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
int num = 0, res = 0, len = numbers.size(), maxx = 0;
for(int i = 0; i < len; i++)
{
if(res == numbers[i]) num++;
else
{
if(num > 0) num--;
if(num == 0) res = numbers[i], num = 1;
}
}
for(int i = 0; i < len; i++)
{
if(numbers[i] == res)
maxx++;
}
return maxx > len/2 ? res : 0;
}
题目描述
HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。你会不会被他忽悠住?(子向量的长度至少是1)
思路:经典的最大连续字段和
int FindGreatestSumOfSubArray(vector<int> array) {
int sum = 0, len = array.size(), maxx = -1000000000;
for(int i = 0; i < len; i++)
{
sum += array[i];
maxx = max(maxx, sum);
if(sum < 0) sum = 0;
}
return maxx;
}
题目描述
把只包含因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
思路:丑数肯定是丑数*丑数来的,第一个是1,那么我们肯定从1*2,1*3,1*5找一个最小的,是2,那么已经确定好顺序的丑数有1,2,这时候应该找2*2,1*3,1*5哪个最小了,可以发现2不会再跟1乘一遍了,所以要有3个变量记录之前哪个丑数分别被2,3,5乘过就好了
int GetUglyNumber_Solution(int index) {
if(index == 0) return 0;
int a[index+5], pos2 = 1, pos3 = 1, pos5 = 1, ans = 1;
a[1] = 1;
for(int i = 2; i <= index; i++)
{
a[i] = min(a[pos2]*2, min(a[pos3]*3, a[pos5]*5));
if(a[i] == a[pos2]*2) pos2++;
if(a[i] == a[pos3]*3) pos3++;
if(a[i] == a[pos5]*5) pos5++;
}
return a[index];
}
题目描述
用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
思路:讨论区一个大神讲的很清楚了
用两个栈实现一个队列的功能?要求给出算法和思路!
<分析>:
入队:将元素进栈A
出队:判断栈B是否为空,如果为空,则将栈A中所有元素pop,并push进栈B,栈B出栈;
如果不为空,栈B直接出栈。
用两个队列实现一个栈的功能?要求给出算法和思路!
<分析>:
入栈:将元素进队列A
出栈:判断队列A中元素的个数是否为1,如果等于1,则出队列,否则将队列A中的元素 以此出队列并放入队列B,直到队列A中的元素留下一个,然后队列A出队列,再把 队列B中的元素出队列以此放入队列A中。
class Solution
{
public:
void push(int node)
{
stack1.push(node);
}
int pop()
{
if(stack2.empty())
{
while(!stack1.empty())
{
stack2.push(stack1.top());
stack1.pop();
}
}
int t = stack2.top();
stack2.pop();
return t;
}
private:
stack<int> stack1;
stack<int> stack2;
};