问题:
给定一个只包含小写字母的有序数组letters
和一个目标字母 target
,寻找有序数组里面比目标字母大的最小字母。
数组里字母的顺序是循环的。举个例子,如果目标字母target = 'z'
并且有序数组为 letters = ['a', 'b']
,则答案返回 'a'
。
示例:
输入:letters = ["c", "f", "j"],target = "a"
输出:"c"
输入:letters = ["c", "f", "j"],target = "c"
输出:"f"
输入:letters = ["c", "f", "j"],target = "d"
输出:"f"
输入:letters = ["c", "f", "j"],target = "g"
输出:"j"
输入:letters = ["c", "f", "j"],target = "j"
输出:"c"
输入:letters = ["c", "f", "j"],target = "k"
输出:"c"
注:
-
1. letters
长度范围在[2,10000]
区间内。 -
2. letters
仅由小写字母组成,最少包含两个不同的字母。 -
3. 目标字母
target
是一个小写字母。
思路及代码:
#include<stdio.h>
#include<stdlib.h>
char nextGreatestLetter(char* letters, int lettersSize, char target);
void main(void){
char result;
char letters[4] = {"cfj"};
int lettersSize = 3;
char target = 'c';
result = nextGreatestLetter(letters, lettersSize, target);
printf("%c\n", result);
system("pause");
}
////二分查找(做错啦,查找了相同字符的下一个字符)
//char nextGreatestLetter(char* letters, int lettersSize, char target){
// //char result = '0';
// int low = 0;
// int high = lettersSize - 1;
// int mid = 0;
// //while(mid != lettersSize-2){ //结束判断条件选的不好,如果是letters=cfg,target=c,那么循环没有执行。
// //while(result = '0'){ //结束判断条件选的不好,如果是letters=abc,target=c,那么就陷入了死循环。
// while(low <= high){ //如果这样选结束判断条件,那么low=mid+1,high=mid-1,不然死循环。
// mid = (low + high) / 2;
// if(letters[mid] < target)
// low = mid + 1;
// else if(letters[mid] > target)
// high = mid - 1;
// else{
// if(mid < lettersSize-1) return letters[mid+1];
// else return letters[0];
// }
// }
// return letters[0];
//}
//二分查找(更快)
char nextGreatestLetter(char* letters, int lettersSize, char target){
int low = 1; //low要从1开始,不然后面的[mid-1]下表索引会溢出。
int high = lettersSize - 1;
int mid;
while(low <= high){
mid = (low + high) / 2;
if(letters[mid-1] <= target && letters[mid] > target)
return letters[mid];
else if(letters[mid-1] > target)
high = mid - 1;
else
low = mid + 1;
}
return letters[0];
}
////遍历字符数组(一次遍历)
//char nextGreatestLetter(char* letters, int lettersSize, char target) {
// char result;
// int i = 0;
// while(i<lettersSize){
// switch(letters[i++] > target){
// case 1:
// result = letters[--i]; //这里需注意,因为上一步switch判断之后做了加一操作,所以这里索引要减一,并且是先减再输出。
// return result;
// case 0:
// break;
// }
// }
// result = letters[0];
// return result;
//}
知识点:
1. 程序报错:error: control reaches end of non-void function
原因:可能某个(些)函数本该有返回值,但结果可能无返回值。通常出现在判断语句(如if-else, switch-case等)、循环语句(for, while等)之后,判断和循环之后一定要记得考虑一下最后是否需要返回值,因为可能程序一进来就不符合判断/循环条件!
2. switch-case语句用法:(参考:switch-case用法(值匹配、范围匹配))
switch(值或表达式){
case 值1:
操作1;
break; //不写break会穿透到下一个break
case 值2:
操作2;
break;
case 值3:
操作3;
break;
……
default:
如果表达式的值和以上的case后面的值都没有匹配上,那么就执行这里的代码。
break;
}
//在执行switch-case结构的时候遇到了break,就会结束这个switch-case。
//break是可以省略的,如果省略了break,就会往下一个case项穿透,直到遇到break或者这个switch-case结束为止。
//default是可以省略的,不会有语法错误。如果switch后面的表达式有可能出现的值都在case项里面被罗列出来了,那么就永远不可能执行default,此时就可以省略default。(反正我不建议省略)