第13章:算法

一、字符串反转

	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);

 

二、链表反转

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

 

三、有序数组合并

	// 将有序数组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数组的值
	            result[i] = a[p];
	            // 移动a数组的遍历指针
	            p++;
	        }
	        else{
	            // 存储b数组的值
	            result[i] = b[q];
	            // 移动b数组的遍历指针
	            q++;
	        }
	        // 指向合并结果的下一个存储位置
	        i++;
	    }
	    // 如果a数组有剩余
	    while (p < aLen) {
	        // 将a数组剩余部分拼接到合并结果的后面
	        result[i] = a[p++];
	        i++;
	    }
	    // 如果b数组有剩余
	    while (q < bLen) {
	        // 将b数组剩余部分拼接到合并结果的后面
	        result[i] = b[q++];
	        i++;
	    }
	}

 

四、Hash算法

     面试时往往不是让面试者实现一个hash算法,而是给出一个具体场景,如:在一个字符串中找到第一个只出现一次的字符?

     思路:字符(char)是一个长度为8的数据类型,因此总共有256种可能。每个字母根据其ASCII码值作为数组的下标对应数组的一个值,这个值记录该字符出现的次数。此处的hash函数就是通过给定字母得到其ASCII码值。代码如下:

	// 查找第一个只出现一次的字符
	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;
	}

 

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

     倒叙比较找到第一个不一样的视图,此时前面遍历过的视图都是共同父视图。代码如下:

	- (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 = [arrayOther 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];
	        // 顺着superview指针一直向上查找
	        temp = temp.superview;
	    }
	    return result;
	}

 

六、求无序数组当中的中位数

     当n为奇数时,中位数为(n+1)/2;当n为偶数时,中位数为有两个。本节基于快排查找中位数。代码如下:

	//求一个无序数组的中位数
	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;
	}

七、常用排序算法

     参考我的博客。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值