一、哈希算法
在一个字符串中找到第一个只出现一次的字符。例如:输入“abaccdeff”输出b。
思路:考察hash的使用,利用每个字母的ASCII码作hash来作为数组的index。使用一个数组存储每个字母出现的次数,数组记录的内容是该字母出现的次数,最终遍历字符串,找到第一个数组内容为1的字母即可。时间复杂度为O(n)。
char findFirstChar(char *cha) {
char result = '\0';
// 用于存放每个字符出现的次数,下标为字符的ASCII值
int array[256] = {0};
char *p = cha;
// 遍历字符串,根据ASCII值存入数组中
while (*p != '\0') {
// 字符对应的存储位置,进行次数+1操作。
array[*(p++)]++;
}
//重置p指针
p = cha;
while (*p != '\0') {
// 遇到第一个出现次数为1的字符,打印出结果。
if (array[*p] == 1) {
result = *p;
break;
}
p++;
}
return result;
}
测试代码:
void hash_findFirstCharTest() {
char *cha = "gabaccdeff";
char fc = findFirstChar(cha);
printf("this char is %c \n", fc);
}
输出结果:
this char is g
二、 查找两个子视图的共同父视图
思路:记录视图A的所有父视图存放到数组A。将视图B的所有父视图存放到数组B。然后倒序比较两个数组中的视图,当比较到第一个不一样时,之前找到的就是所有共同父视图。
示例代码:
- (NSArray<NSView *> *)findCommonSuperView:(NSView *)view other:(NSView *)viewOther {
// 结果数组
NSMutableArray *result = [NSMutableArray array];
// 两个子视图所有父视图组成的数组。
NSArray *aSuperViews = [self findSuperView:view];
NSArray *bSuperViews = [self findSuperView:viewOther];
int i = 0;
// 越界条件选取小的那个
while (i < MIN(aSuperViews.count, bSuperViews.count)) {
NSView *aSuperView = [aSuperViews objectAtIndex:aSuperViews.count - i - 1];
NSView *bSuperView = [bSuperViews objectAtIndex:bSuperViews.count - i - 1];
// 比较是否相等,相等则为共同父视图。不相等结束遍历。
if (aSuperView == bSuperView) {
[result addObject:aSuperView];
i++;
} else {
break;
}
}
return result;
}
- (NSArray <NSView *> *)findSuperView:(NSView *)view {
// 第一个父视图
NSView *temp = view.superview;
NSMutableArray *result = [NSMutableArray array];
while (temp) {
[result addObject:temp];
temp = temp.superview;
}
return result;
}
注意引入的是
AppKit
所以视图为NSView
。
三、无序数组中的中位数。
方案:排序算法 + 中位数;利用快排思路(分治思想)。
关于排序算法这里不再赘述,可以网上搜索。
中位数:当n为奇数时,(n + 1)/2 ;当n为偶数时,(n / 2 + (n / 2 + 1)/ 2。
思路:快排思想。任意选择一个元素,以该元素为支点划分数组为两部分,如果左侧集合长度恰好为(n -1)/2,那么支点就是中位数。如果左侧长度小于(n - 1)/2,那么中位数在右侧,否则中位数在左侧。
示例代码:
// 无序数组的中位数
int findMedian(int a[], int aLen) {
int low = 0;
int high = aLen - 1;
// 中位下标
int mid = (aLen - 1) / 2;
// 第一遍快排
int div = PartSort(a, low, high);
while (div != mid) {
if (mid < div) {
// 左半区间
div = PartSort(a, low, div - 1); // 递归
} else {
//右半区间
div = PartSort(a, div + 1, high); // 递归
}
}
return a[mid];
}
int PartSort(int a[], int start, int end) {
// 两个哨兵
int low = start;
int high = end;
// 关键数
int key = a[end];
while (low < high) {
// 左边的值要比Key小
while (low < high && a[low] <= key) {
++low;
}
// 右边的值要比Key大
while (low < high && a[high] >= key) {
--high;
}
// 交换两个哨兵对应的值
if (low < high) {
int temp = a[low];
a[low] = a[high];
a[high] = temp;
}
}
// 交换关键数
int temp = a[high];
a[high] = a[end];
a[end] = temp;
return low;
}
测试代码:
void findMedianTest() {
int list[9] = {12,3,10,8,6,7,11,13,9};
// 3 6 7 8 9 10 11 12 13
// ^
int median = findMedian(list, 9);
printf("the median is %d \n", median);
}
输出结果:
the median is 9