题目名称:字符串全排列
题目描述
对K个不同字符的全排列组成的数组, 面试官从中随机拿走了一个, 剩下的数组作为输入, 请帮忙找出这个被拿走的字符串? 比如[“ABC”, “ACB”, “BAC”, “CAB”, “CBA”] 返回 “BCA”
输入描述:
第一行输入整数n,表示给定n个字符串。(n == x!-1,2<=x<=10) 以下n行每行输入一个字符串。
输出描述:
输出全排列缺少的字符串。
示例
输入
5
ABC
ACB
BAC
CAB
CBA
输出
BCA
分析
1.第一个问题:因为输入时输入了当前输入的元素个数,以及缺失了部分元素的部分全排列元素。所以我们首先要考虑如何获得全排列元素,通过定义一个permute函数嵌套调用实现;
2.第二个问题:全排列元素已经获得,那怎么确定哪个元素缺失了。我通过遍历全排列元素,如果当前元素用户已经输入,则直接跳转到下一个元素,如果当前元素遍历了用户输入的元素后仍然没找到,则打印出来。
带着这两个核心思想,我的代码实现如下
代码示例
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void swap(char *x, char *y) {
char temp;
temp = *x;
*x = *y;
*y = temp;
}
//计算出全排列所有元素,并判断全排列中哪个元素未出现过
void permute(char *a, int l, int length, int n, char **arr) {
int i;
// l = length时,说明是一个完整的排列元素,继续进行处理
if (l == length) {
int count = 0;
for (int j = 0; j < n; j++) {
if (strstr(arr[j], a) == NULL) {
count++;
} else {
//一旦找到元素,则不需要再遍历了,直接return
return;
}
// 遍历arr后仍然未找到当前全排列中的某个元素,打印出来
if (count)
printf("%s\n", a);
} else {
for (i = l; i < length; i++) {
swap((a+l), (a+i));
permute(a, l+1, length, n, arr);
swap((a+l), (a+i)); // backtrack
}
}
}
void solution(int n, char **arr){
int length = strlen(arr[0]);
char str[length];
memcpy(str, arr[0], sizeof(arr[0]));
permute(str, 0, length, n, arr);
}
int main() {
int n;
scanf("%d", &n);
char** arr;
arr = (char**)malloc(n * sizeof(char*));
for (int i = 0; i < n; i++){
arr[i] = (char*)malloc(sizeof(char));
}
for (int i = 0; i < n; i++)
{
scanf("%s", arr[i]);
}
solution(n, arr);
return 0;
}
题目名称:小股炒股
题目描述
已知n天后的股票行情,现在已有的本金是m, 规定只能入手一次股票和抛售一次股票。 最大收益是?
输入描述:
第一行输入整数n,m。(1<=n<=1000,1<=m<=10000) 第二行输入n个整数表示某股票单股价格p。(1<=p<=1000)
输出描述:
输出小最大收益
示例
输入
2 4
3 7
输出
8
分析
这题其实没什么可说的,没什么难度。题目也很友好地把难度降低了:只能买、卖一次。所以只要遍历行情列表,通过比较不同买入点和卖出点的收益,找出最大收益时的买点和卖点即可,时间复杂度是。必定存在更优化的方案,但在比赛的时候来不及细想,我记得题目提示了,所以穷举完全可以pass。
要注意的是,因为卖出的时间点必在买入之后,所以内循环只要从买入那天的隔天开始,到最后一天结束即可。
代码示例
#include <stdio.h>
#include <stdlib.h>
void solution(int n, int m, int *plist){
int max_profit = 0;
for (int i = 0; i < n; i++) {
int buy = plist[i];
for (int j = i + 1; j < n; j++) {
int sell = plist[j];
if (sell > buy) {
int profit = (m / buy) * sell + m % buy;
if (profit > max_profit)
max_profit = profit;
}
}
}
printf("%d\n", max_profit);
}
int main() {
int tem_arr[2];
for (int i = 0; i < 2; i++)
{
scanf("%d", &tem_arr[i]);
}
int n = tem_arr[0];
int m = tem_arr[1];
int* plist;
plist = (int*)malloc(n * sizeof(int));
for (int i = 0; i < n; i++)
{
scanf("%d", &plist[i]);
}
solution(n, m, plist);
return 0;
}
题目名称:最小H值
题目描述
给你一个二维 rows x columns 的地图 heights , 其中 heights[row][col] 表示格子 (row, col) 的高度。 一开始你在最左上角的格子 (0, 0) , 且你希望去最右下角的格子 (rows-1, columns-1) (注意下标从 0 开始编号)。 你每次可以往 上,下,左,右 四个方向之一移动,你想要找到H值最小的一条路径。 一条路径的 H值 是路径上相邻格子之间 高度差绝对值 的 最大值 决定的。 请你返回从左上角走到右下角的最小H值。
输入描述:
输入:heights = [[1,2,2],[3,8,2],[5,3,5]]
输出描述:
输出:2 解释:路径 [1,3,5,3,5] 连续格子的差值绝对值最大为 2 。 这条路径比路径 [1,2,2,2,5] 更优,因为另一条路径差值最大值为 3 。
示例
输入
* 输入样例1
```
[[1,2,2],[3,8,2],[5,3,5]]
```
* 输入样例2
```
`[[1,2,1,1,1],[1,2,1,2,1],[1,2,1,2,1],[1,2,1,2,1],[1,1,1,2,1]]`
```
输出
* 输出样例1
`2`
* 输出样例2
`0`
分析
这道题是考察图的问题,把每个格子都当作图的一个节点,相邻格子之间的差的绝对值当作边的权重,这样就可以把输入的矩阵转化成图的形式。
其中紫色表示的即为该图体力消耗最小的路径,消耗体力值为该路径的最大权重2
对于这道题我们可以采用并查集的做法,所以这道题就是求从最左上角的点到最右下角的点的连通性问题
首先,我们可以先把 图中所有的边都去掉,变成这个样子
然后添加权重最小的边0,发现添加完0边之后,没有连通起来,因此0不是最小体力消耗值,继续走
然后添加权重为1的边,发现还是没有连通起来,因此1也不是最小体力消耗值,然后添加权重为2的边,发现最左上角与最右下角连通起来了,因此2是最小体力消耗
在这道题中,并查集的作用就是判断最左上角的点和最右下角的点是否连通,同时在添加一条边时,如果该边的两个节点未连通,则将两个节点连通起来
代码示例
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MAX_ROWS 100
#define MAX_COLS 100
int minH(int** heights, int rows, int columns) {
int dp[rows][columns];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
if (i == 0 && j == 0) {
dp[i][j] = abs(heights[i][j] - heights[0][0]);
} else if (i == rows - 1 && j == columns - 1) {
dp[i][j] = 0;
} else {
dp[i][j] = INT_MAX;
if (i > 0) {
dp[i][j] = min(dp[i][j], dp[i-1][j] + abs(heights[i][j] - heights[i-1][j]));
}
if (j > 0) {
dp[i][j] = min(dp[i][j], dp[i][j-1] + abs(heights[i][j] - heights[i][j-1]));
}
if (i < rows - 1) {
dp[i][j] = min(dp[i][j], dp[i+1][j] + abs(heights[i][j] - heights[i+1][j]));
}
if (j < columns - 1) {
dp[i][j] = min(dp[i][j], dp[i][j+1] + abs(heights[i][j] - heights[i][j+1]));
}
}
}
}
return dp[0][0];
}