第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;
	}

七、常用排序算法

     參考我的博客。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章