几道常见的算法面试题

字符串反转

将字符串hello, world反向输出

void char_reverse(char*cha){
  //    指向第一个字符
  char * begin = cha;
  //  指向最后一个字符
  char * end = cha + strlen(cha) -1;

  while (begin < end){
    //交换两个字符的位置,并向中间移动一位
    char temp = *begin;
    *(begin ++) = *end;
    *(end--) = temp;
  }
}

  char ch[] = "hello,world";
  char_reverse(ch);
  printf("reverse result is %s",ch);

链表反转

链表反转

ReverseList.h

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN
//定义一个链表
struct Node {
    int data;
    struct Node * next;
};
@interface ReverseList : NSObject
//链表反转
struct Node * reverseList(struct Node * head);
//构造一个链表
struct Node * constructList(void);
//打印链表中的数据
void printList(struct Node * head);

@end

ReverseList.m

#import "ReverseList.h"

@implementation ReverseList

struct Node * reverseList(struct Node * head){
    //定义遍历指针,初始化为头节点
    struct Node * p = head;
    //反转后的b链表头部
    struct Node * newH = NULL;
    while (p != NULL) {
        //记录下一个节点
        struct Node * temp = p->next;
        //当前节点的next指向新链表头部
        p->next = newH;
        //更改新链表头部为当前节点
        newH = p;
        //移动p指针
        p = temp;
    }
    //返回反转后的链表头节点
    return newH;
}

//构造一个链表
struct Node * constructList(void){
    //头节点定义
    struct Node * head = NULL;
    //记录当前节点尾节点
    struct Node * cur = NULL;
    for (int i = 1; i < 5; i++) {
        struct Node * node = malloc(sizeof(struct Node));
        node->data = I;
        
        if (head == NULL) {
            head = node;
        }
        else{
            //当前节点的next为新节点
            cur->next = node;
        }
        cur = node;
    }
    return head;
}

//打印链表中的数据
void printList(struct Node * head){
    
    struct Node * temp = head;
    while (temp != NULL) {
        printf("node is %d \n",temp->data);
        temp = temp->next;
    }
}

@end

调用

    //单链表反转
    struct Node * head = constructList();
    printList(head);
    printf("--------------------\n");
    struct Node * newHead = reverseList(head);
    printList(newHead);

有序数组合并

有序数组合并

思想

思想

如上图,比较p、q两个指针分别指向的数据大小,小的填充带新数组中,兵移动相应指针,大的数据指针不动,然后继续这样比较,当一个数组的数据被完全填充后, 把另一个数组的数据依次填充到新数组中。

算法实现
MergeSortedList.h

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface MergeSortedList : NSObject
//将有序数组a和有序数组b合并到一个数组result当中,且仍然保持有序
void mergeList(int a[], int aLen, int b[], int bLen, int result[]);
@end

NS_ASSUME_NONNULL_END

MergeSortedList.m

#import "MergeSortedList.h"

@implementation MergeSortedList
//将有序数组a和有序数组b合并到一个数组result当中,且仍然保持有序
void mergeList(int a[], int aLen, int b[], int bLen, int result[])
{
    int p = 0;//遍历数组a的指针
    int q = 0;//遍历数组b的指针
    int i = 0;//记录当前储存位置
    //任一数组没有达到边界遍历
    while (p < aLen && q < bLen) {
        //如果a数组对应位置小于b数组对应位置的值
        if (a[p] < b[q]) {
            //储存a数组的b值
            result[i] = a[p];
            //移动p指针的位置
            p++;
        }
        else{
            //储存b数组的b值
            result[i] = b[q];
            //移动q指针的位置
            q++;
        }
        I++;
    }
    //如果a数组有剩余
    while (p < aLen) {
        result[i] = a[p++];
        I++;
    }
    //如果b数组有剩余
    while (q < bLen) {
        result[i] = b[q++];
        I++;
    }
    
}
@end

算法调用

    int a[5] = {1,4,6,7,9};
    int b[8] = {2,3,5,6,8,10,11,12};

    int result[13];
    mergeList(a, 5, b, 8, result);
    for (int i = 0; i < 13; i++) {
        printf("%d  ",result[I]);
    }

Hash算法

在一个字符串中找出第一个只出现一次的字符;
如:输入abccdeff,则输出 b

算法思路
  • 字符(char)是一个长度为8的数据类型,因此用功有2^8 =256种可能
  • 每个字母根据其ASCII码值作为数组的下标对应数组的一个数字
  • 数组中存储的是每个字符出现的次数
哈希表概念

例:给定值是字母a,对应的ASCII值是97,数组索引下标为97

char ----f(key)---->index
f(key) = key
·存储和查找都通过该函数,有效提高查找效率·

算法实现
///查找第一个只出现一次的字符
char findFirstChar(char * cha){
    char result = '\0';
    //定义一个数组用来存储哥哥字母出现的次数
    int array[256];
    //对数组进行初始化操作
    for (int i = 0; i<256; i++) {
        array[i] = 0;
    }
    //定义一个指针 指向当前字符串的头部
    char * p = cha;
    //遍历每个字符
    while (*p != '\0') {
        //在字母对应存储位置 进行出现洗漱+1操作
        array[*(p++)]++;
    }
    //  将P值装重新指向字符串头部
    p = cha;
    //  遍历每个字母出现的次数
    while (*p != '\0') {
        //遇到第一个出现次数为1的字符打印结果
        if (array[*p] == 1) {
            result = *p;
            break;
        }
        //反之继续查找
        p++;
    }
    return result;
    
}

 char cha[] = "abaccdeff";
 char fc = findFirstChar(cha);
 printf("this char is %c \n",fc);

查找两个子视图的共同父视图

思路:


查找两个子视图的共同父视图
算法实现
///查找两个视图的共同父视图
- (NSArray<UIView *> *)findCommonSuperView:(UIView *)viewOne other:(UIView *)viewOther{
    NSMutableArray * result = [NSMutableArray array];
    //查找第一个视图的所有父视图
    NSArray * arrayOne = [self findSuperViews:viewOne];
    //查找第二个视图的所有父视图
    NSArray * arrayOther = [self findSuperViews:viewOther];
    
    int i = 0;
    while (i < MIN((int)arrayOne.count, (int)arrayOther.count)) {
        //倒序获取各个视图的父视图
        UIView * superOne = [arrayOne objectAtIndex:arrayOne.count - i - 1];
        UIView * superOther = [arrayOne objectAtIndex:arrayOther.count - i - 1];
        
        if (superOne == superOther) {
            [result addObject:superOne];
            I++;
        }
        //如果不相同,结束遍历
        else{
            break;
        }
    }
    
    return result;
}


-(NSArray <UIView *>*)findSuperViews:(UIView *)view{
    //初始化为第一父视图
    UIView * temp = view.superview;
    //保存结果的数组
    NSMutableArray * result = [NSMutableArray array];
    while (temp) {
        [result addObject:temp];
        temp = temp.superview;
    }
    return result;
    
}

无序数组求中位数

首先理解一下中位数,比如[1,3,5,7,8],那么中位数就为“5”,若是[1,3,5,7,8,10],那么中位数便为中间两位的平局值,即(5+7)/2 = 6;

那么无序数组求中位数,有哪些方法?

  1. 排序算法+中位数
  2. 利用快排思想(分治思想)
排序算法+中位数

冒泡排序、快速排序、堆排序……

中位数
当n为奇数,为(n+1)/2;
当n为偶数,为((n/2)+(n/2)+1)/2;

快排思想

选取关键字,高低交替扫描


快排思想
  • 任意挑选一个元素,以该元素为支点,划分集合为两部分。
  • 如果左侧集合长度恰好为(n-1)/2,那么支点恰为中位数。
  • 如果左侧长度小于(n-1)/2,那么中位点在右侧;反之,中位数在右侧。
  • 进入相应一侧继续寻找中位点。
算法实现
///无序数组中查找中位数
float findMideian(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) ;
        }
    }
    if (aLen % 2 == 1) {
        //若为奇数
        return a[mid];
    }
    else{
        //若为偶数
        int mid1 = (aLen + 1)/2;
        while (div != mid1) {
            if (mid1 < div) {
                //左半区找
                div = PartSort(a, low, div - 1) ;
            }
            else{
                //右半区找
                div = PartSort(a, div + 1, high) ;
            }
        }
        return (a[mid] + a[mid1])/2.0;
    }
    
}

///快排
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;
}

具体源码可在这里查看。

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

推荐阅读更多精彩内容