美文网首页
iOS面试常考算法(持续更新)

iOS面试常考算法(持续更新)

作者: 妹子爱编程 | 来源:发表于2019-03-25 16:55 被阅读0次

    1.字符串翻转

       char str[] = "abcde";
       reservString(str);
    

    reservString具体实现如下

        void reservString(char* str){
              //算法基本思路就是头尾指针指向字符串的头部和尾部,然后依次交换头尾指针的值。循环的终止条件是头指针小于尾指针
              char* begin = str;
              char* end = str + strlen(str) - 1;
              while (begin < end) {
                  char temp = *begin;
                  *(begin++) = *end;
                  *(end--) = temp;
               }
    
              printf("%s",str); //输出edcba
         }
    

    2.链表原地翻转

        //定义一个链表节点
        struct Node{
            int data;
            struct Node *next;
        };
        //几个链表操作的基本方法
        //1构建一个链表
        struct Node* constructList(void){
            struct Node* head = NULL;
            struct Node* cur = NULL;
            for (int i = 0; i < 10; i++) {
                struct Node* node = malloc(sizeof(struct Node));
                node->data = rand() % 100;
                if(head == NULL){
                    head = node;
                }else{
                    cur->next = node;
                }
                  //设置当前节点为新节点
                cur = node;
            }
    
            cur->next = NULL;
            return head;
        }
        //2.打印一个链表
        void printList(struct Node* head){
            struct Node* cur = head;
            while (cur != NULL) {
                printf("%d->",cur->data);
                cur = cur->next;
            }
            printf("NULL\n");
        };
        //3.原地翻转链表并返回新链表的头结点,头插法
       struct Node* reverseList(struct Node* head){
            struct Node* p = head;
            struct Node* newH = NULL;
            while (p != NULL) {
                struct Node* temp = p;
                p = p->next;
                temp->next = newH;
                newH = temp;
            }
            return newH;
        }
        //测试代码
        struct Node* head = constructList();
        printList(head);
        //打印出来:7->49->73->58->30->72->44->78->23->9->NULL
        struct Node* newH =  reverseList(head);
        printList(newH);
        //打印结果:9->23->78->44->72->30->58->73->49->7->NULL
    

    3.合并有序数组,尽可能快

        void chainSortArray(int aArray[], int aLen,int bArray[],int bLen,int result[]){
            int aIndex = 0;
            int bIndex = 0;
            int sortIndex = 0;
            while (aIndex < aLen && bIndex < bLen) {
                if(aArray[aIndex] < bArray[bIndex]){
                    result[sortIndex] = aArray[aIndex];
                    aIndex++;
                }else{
                    result[sortIndex] = bArray[bIndex];
                    bIndex++;
                }
                sortIndex++;
            }
    
            //将剩下没有比较完的数组的东西放到数组中
            while (aIndex < aLen) {
                result[sortIndex] = aArray[aIndex++];
                sortIndex++;
            }
    
              while (bIndex < bLen) {
                result[sortIndex] = bArray[bIndex++];
                sortIndex++;
            }
    
       }
        //测试用例ex:
            int a[] = {0,8,9,10,13,16};
            int b[] = {1,4,7,8,45};
            int result[11] = {0};
            chainSortArray(a, 6, b, 5, result);
            for (int i = 0; i < 11; i++) {
                printf("%d,",result[i]);
                //打印结果:0,1,4,7,8,8,9,10,13,16,45,
             }
    

    4.查找一个字符串中第一个出现1次的字符

        char hashFind(char *str){
            //采用hash算法的思想 hash算法就是字符ascii码就是对应的hash index
            int array[256] = {0};
            char *p = str;
            while (*p != '\0') {
                  array[*p]++;
                  p++;
            }
    
            p = str;
            //**这里注意** 这里是遍历原来的字符数组,而不是遍历hash 数组
            while (*p != '\0') {
                if(array[*p] == 1){
                    return *p;
                }
                p++;
            }
    
            return *p;
        }
    

    5.求x的n次方

        //递归的思想,而且需要考虑边界条件
        double qart(double x, int n){
            if(n == 0){
                return 1;
            }else if(n > 0){
                return qart_sub(x, n);
            }else{
                return  1 / qart_sub(x, abs(n));
            }
        }
    
    
        double qart_sub(double x, int n){
            if(n == 0){
                  return 1;
           }else {
                return x * qart(x, n - 1);
            }
            return x;
        }
        //测试用例ex:
        double res = qart(2, -5);
         printf("结果为:%.6f\n",res); //结果为:0.031250
    

    6.写一个快速排序

        //将从left起到right的子数组 做中间元素的分割
        int partition(int arr[], int left,  int right){
            int i = left;
            int j = right;
            int tmp = arr[left];
            while (i < j) {
                //从右往左扫描
                while (i < j && arr[j] > tmp) {
                    j--;
                }
                //遇到比分割元素小的元素,将元素挪到数组左边填坑
                if(i < j){
                    arr[i] = arr[j];
                    i++;
                }
                //从左往右扫描
                while (i < j && arr[i] < tmp) {
                    i++;
                }
                //遇到比b分割元素大的元素,将元素挪到数组右边填坑
                if(i < j){
                    arr[j] = arr[i];
                    j--;
                }
            }
            //放置分割元素,arr[left,i-1] 全部小于 arr[i] arr[i+1,right]全部大于arr[i]
            arr[i] = tmp;
            return i;
        }
    
        void quickSort(int array[],int left, int right){
            if (left > right)
                return;
            int j = partition(array, left, right);
            //分治法,划分子问题,递归解决子问题
            quickSort(array, left, j-1);
            quickSort(array, j+1, right);
    
        }
        //测试ex:
        int arrayEx[20] = {0};
            for (int i = 0; i < 20; i++) {
                arrayEx[i] = arc4random() % 100;
            }
            quickSort(arrayEx, 0, 19);
    
            for(int i = 0; i < 20; i++){
                printf("%d,",arrayEx[i]);
            }
          //输出:8,11,12,20,20,28,43,46,48,52,55,65,66,70,72,74,76,78,80,99,
    

    7.求一个无序数组的中位数

       // 使用快速排序的思想,左右交替扫描
      int findMedianNumber(int array[], int aLen){
    
            //中位数的在数组中的index
            int mid = (aLen - 1)/2;
            //利用快排的分割思想
            int div = partition(array, 0, aLen - 1);
            while (mid != div) {
                if(mid < div){
                    div = partition(array, 0, div - 1);
                }else{
                    div = partition(array, div + 1, aLen - 1);
                }
            }
            return array[mid];
        }
        //测试用例ex:
         int array2[] = {2,13,9,5,7,20,18,3,8,10};
        int median = findMedianNumber(array2, 10);
        printf("中位数%d",median);
        //输出 8
    

    8.求一个链表的中间节点

        //采用快慢指针的方式
        //返回中间节点
        struct Node* findLinkMedian(struct Node *head){
            //一次走一步
            struct Node* slowPtr = head;
            //一次走两步
            struct Node* fastPtr = head;
    
            while (fastPtr != NULL) {
              //当快指针走到最后的时候,慢指针指向的就是中间节点
               if(fastPtr->next == NULL){
                    break;
                }
                slowPtr = slowPtr->next;
                fastPtr = fastPtr->next->next;
            }
            return slowPtr;
        }
        //测试代码ex:用到了前面2链表翻转的数据结构和方法
         struct Node *head1 = constructList();
            printList(head1);
            struct Node* medianNode = findLinkMedian(head1);
            printf("中间节点是 %d",medianNode->data);
            //答应结果:
            //3->69->9->57->60->33->99->78->16->35->97->26->12->67->10->33->79->49->79->21->NULL
            //中间节点是 97
    

    9.求两个view的共同父视图

    10.检测链表中是否有环

        //链表中环的检测
            int isHaveCircleInList(struct Node *head){
            //定义两个指针 快慢指针 如果快慢指针能相遇 说明有环的存在
            if (head == NULL) {
                return 0;
            }
    
            if(head->next == NULL){
                return 0;
            }
    
            struct Node* slowHead = head;
            struct Node* fasthead = head;
            while (slowHead != NULL && fasthead != NULL) {
                slowHead = slowHead->next;
                fasthead = fasthead->next->next;
                if(slowHead == fasthead){
                    return 1;
                }
            }
            return 0;
        }
    

    11.两个有序链表的合并

        //两个有序的链表合并
        struct Node* mergerTwoOrderList(struct Node* list1, struct Node* list2){
            if(list1 == NULL){
                return list2;
            }
            if(list2 == NULL){
                return list1;
            }
    
            struct Node *cur1 = list1;
            struct Node *cur2 = list2;
            struct Node *newHead = NULL;
            struct Node *cur = NULL;
            while (cur1 != NULL && cur2 != NULL) {
                if(cur1->data < cur2->data){
                    if(newHead == NULL){
                        newHead = cur1;
                        cur = newHead;
                    }else{
                        cur->next = cur1;
                        cur = cur1;
                    }
                    cur1 = cur1->next;
                  }else{
                      if(newHead == NULL){
                          newHead = cur2;
                        cur = newHead;
                    }else{
                        cur->next = cur2;
                        cur = cur2;
                    }
                    cur2 = cur2->next;
                }
            }
    while (cur1 != NULL) {
        cur->next = cur1;
        cur = cur1;
        cur1 = cur1->next;
    }
    
    while (cur2 != NULL) {
        cur->next = cur2;
        cur = cur2;
        cur2 = cur2->next;
    }
    cur->next = NULL;
    return newHead;
        }
    

    相关文章

      网友评论

          本文标题:iOS面试常考算法(持续更新)

          本文链接:https://www.haomeiwen.com/subject/vszvvqtx.html