第一题:平分的直线
题目:
在二维平面上,有两个正方形,请找出一条直线,能够将这两个正方形对半分。假定正方形的上下两条边与x轴平行。
给定两个vecotrA和B,分别为两个正方形的四个顶点。请返回一个vector,代表所求的平分直线的斜率和截距,保证斜率存在。
测试样例:
[(0,0),(0,1),(1,1),(1,0)],[(1,0),(1,1),(2,0),(2,1)]
返回:[0.0,0.5]
解析:
平分正方形的直线必定经过正方形的中心
struct Point {
int x;
int y;
Point() :
x(0), y(0) {
}
Point(int xx, int yy) {
x = xx;
y = yy;
}
};
class Bipartition {
public:
vector<double> getBipartition(vector<Point> A, vector<Point> B) {
// write code here
double ax = A[1].x != A[2].x ? (A[1].x + A[2].x) / 2 : (A[0].x + A[2].x) / 2;
double ay = A[0].y != A[1].y ? (A[0].y + A[1].y) / 2 : (A[0].y + A[2].y) / 2;
double bx = B[1].x != B[2].x ? (B[1].x + B[2].x) / 2 : (B[0].x + B[2].x) / 2;
double by = B[0].y != B[1].y ? (B[0].y + B[1].y) / 2 : (B[0].y + B[2].y) / 2;
double k = (by - ay) / (bx - ax);
double b = by - k * bx;
return { k,b };
}
};
第二题:穿点最多的直线
题目:
在二维平面上,有一些点,请找出经过点数最多的那条线。
给定一个点集vectorp和点集的大小n,没有两个点的横坐标相等的情况,请返回一个vector,代表经过点数最多的那条直线的斜率和截距。
解析:
每两个点两辆组合求k和b,用哈希计数
struct Point {
int x;
int y;
Point() :
x(0), y(0) {
}
Point(int xx, int yy) {
x = xx;
y = yy;
}
};
class DenseLine {
public:
vector<double> getLine(vector<Point> p, int n) {
// write code here
map<pair<double, double>, int> hash;
for (int i = 0; i < n - 1; ++i) {
for (int j = i + 1; j < n; ++j) {
double k = (p[j].y - p[i].y) / (p[j].x - p[i].x);
double b = p[j].y - k * p[j].x;
auto tmp = make_pair(k, b);
++hash[tmp];
}
}
vector<double> res(2);
int max = 0;
for (auto it = hash.begin(); it != hash.end(); ++it) {
if (it->second > max) {
max = it->second;
pair<double, double> tmp = it->first;
res[0] = tmp.first;
res[1] = tmp.second;
}
}
return res;
}
};
第三题:第k个数
题目:
有一些数的素因子只有3、5、7,请设计一个算法,找出其中的第k个数。
给定一个数int k,请返回第k个数。保证k小于等于100。
测试样例:
3
返回:7
解析:
class KthNumber {
public:
int findKth(int k) {
// write code here
int now = 3;
vector<int> res;
res.push_back(3);
res.push_back(5);
res.push_back(7);
int last = 0;
while (res.size() <= k) {
last = res[res.size() - 1];
for (int i = 0; i < res.size(); ++i) {
if (res[i] * 3 > last) {
if (now <= last) {
now = res[i] * 3;
}
else
{
now = now < res[i] * 3 ? now : res[i] * 3;
}
if (now < res[i] * 3) break;
}
if (res[i] * 5 > last) {
if (now <= last) {
now = res[i] * 5;
}
else
{
now = now < res[i] * 5 ? now : res[i] * 5;
}
}
if (res[i] * 7 > last) {
if (now <= last) {
now = res[i] * 7;
}
else
{
now = now < res[i] * 7 ? now : res[i] * 7;
}
}
}
res.push_back(now);
}
return res[k - 1];
}
};
第四题:上楼梯
题目:
有个小孩正在上楼梯,楼梯有n阶台阶,小孩一次可以上1阶、2阶、3阶。请实现一个方法,计算小孩有多少种上楼的方式。为了防止溢出,请将结果Mod
1000000007给定一个正整数int n,请返回一个数,代表上楼的方式数。保证n小于等于100000。
测试样例1:
1
返回:1
测试样例2:
3
返回:4
测试样例3:
4
返回:7
解析:
1、递归
2、动态规划
注意:%1000000007的使用
class GoUpstairs {
public:
int countWays(int n) {
// write code here
if (n == 1) return 1;
if (n == 2) return 2;
if (n == 3) return 4;
int last3 = 1;
int last2 = 2;
int last1 = 4;
int now = 0;
for (int i = 4; i <= n; ++i) {
now = ((last1 + last2) % 1000000007 + last3) % 1000000007;
last3 = last2;
last2 = last1;
last1 = now;
}
return now;
}
};
第五题:机器人走方格I
题目:
有一个XxY的网格,一个机器人只能走格点且只能向右或向下走,要从左上角走到右下角。请设计一个算法,计算机器人有多少种走法。
给定两个正整数int x,int y,请返回机器人的走法数目。保证x+y小于等于12。
测试样例:
2,2
返回:2
解析:
注意:
dp[0][j]
和dp[i][0]
等于1
class Robot {
public:
int countWays(int x, int y) {
// write code here
int dp[12][12];
for(int i=0;i<x;i++){
for(int j=0;j<y;j++){
if(i==0)
dp[i][j]=1;
else if(j==0)
dp[i][j]=1;
else
dp[i][j]=dp[i-1][j]+dp[i][j-1];
}
}
return dp[x-1][y-1];
}
};
第六题:机器人走方格II
题目:
有一个XxY的网格,一个机器人只能走格点且只能向右或向下走,要从左上角走到右下角。请设计一个算法,计算机器人有多少种走法。注意这次的网格中有些障碍点是不能走的。
给定一个int[][] map(C++ 中为vector< >),表示网格图,若map[i][j]为1则说明该点不是障碍点,否则则为障碍。另外给定int x,int y,表示网格的大小。请返回机器人从(0,0)走到(x - 1,y - 1)的走法数,为了防止溢出,请将结果Mod1000000007。保证x和y均小于等于50
解析:
class Robot {
public:
int countWays(vector<vector<int> > map, int x, int y) {
// write code here
vector<vector<int> > dp(x, vector<int>(y, 0));
for (int i = 0; i < x; i++) {
for (int j = 0; j < y; j++) {
if (map[i][j] != 1) continue;
if (i == 0 && j == 0) dp[0][0] = 1;
else if (i != 0 && j == 0) dp[i][0] = dp[i - 1][0];
else if (i == 0 && j != 0) dp[0][j] = dp[0][j - 1];
else {
dp[i][j] = (dp[i][j - 1] + dp[i - 1][j]) % 1000000007;
}
}
}
return dp[x - 1][y - 1];
}
};
第七题:魔术索引I
题目:
在数组A[0…n-1]中,有所谓的魔术索引,满足条件A[i]=i。给定一个升序数组,元素值各不相同,编写一个方法,判断在数组A中是否存在魔术索引。请思考一种复杂度优于o(n)的方法。
给定一个int数组A和int n代表数组大小,请返回一个bool,代表是否存在魔术索引。
测试样例:
[1,2,3,4,5]
返回:false
解析:
要优于O(n),使用二分
注意:二分的边界条件
class MagicIndex {
public:
bool findMagicIndex(vector<int> A, int n) {
// write code here
int low = 0, high = A.size() - 1;
while (low <= high) {
int mid = (low + high) / 2;
if (A[mid] == mid) {
return true;
}
else if (A[mid] > mid) {
high = mid - 1;
}
else if (A[mid] < mid) {
low = mid + 1;
}
}
return false;
}
};
第八题:魔术索引II
题目:
在数组A[0…n-1]中,有所谓的魔术索引,满足条件A[i]=i。给定一个不下降序列,元素值可能相同,编写一个方法,判断在数组A中是否存在魔术索引。请思考一种复杂度优于o(n)的方法。
给定一个int数组A和int n代表数组大小,请返回一个bool,代表是否存在魔术索引。
测试样例:
[1,1,3,4,5]
返回:true
解析:
class MagicIndex {
public:
bool findMagicIndex(vector<int> A, int n) {
// write code here
int i = 0;
while (i < n) {
if (A[i] == i) {
return true;
}
else if (A[i] > i) {
i = A[i];
}
else
{
++i;
}
}
return false;
}
};