iOS开发进阶-算法二

课程: 新浪微博资深大牛全方位剖析 iOS 高级面试

一、哈希算法

在一个字符串中找到第一个只出现一次的字符。例如:输入“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

小结

示例代码仓库地址:Algorithm

算法篇暂时告一段落,以上只是几个基本的算法题,仅仅是九牛一毛。推荐两个网站:leetCode牛客网

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容