算法

作者: 余立徽 | 来源:发表于2020-06-17 11:07 被阅读0次

    一、交换A和B的值

    1.中间变量

    void swap(int a, int b) {
    int temp = a;
    a = b;
    b = temp;
    }

    2.加法

    void swap(int a, int b) {
    a = a + b;
    b = a - b;
    a = a - b;
    }

    3.异或(相同为0,不同为1. 可以理解为不进位加法)

    void swap(int a, int b) {
    a = a ^ b;
    b = a ^ b;
    a = a ^ b;
    }

    二、求最大公约数

    1.直接遍历法

    int maxCommonDivisor(int a, int b) {
    int max = 0;
    for (int i = 1; i <=b; i++) {
    if (a % i == 0 && b % i == 0) {
    max = I;
    }
    }
    return max;
    }

    2.辗转相除法

    int maxCommonDivisor(int a, int b) {
    int r;
    while(a % b > 0) {
    r = a % b;
    a = b;
    b = r;
    }
    return b;
    }

    三、排序算法

    当n较大,则应采用时间复杂度为O(nlog2n)的排序方法:快速排序、堆排序或归并排序序。
    快速排序:是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短;

    1、选择排序

    1.选择排序将已排序部分定义在左端,然后选择未排序部分的最小元素和未排序部分的第一个元素交换。

    【选择排序】:最值出现在起始端
    第1趟:在n个数中找到最小(大)数与第一个数交换位置
    第2趟:在剩下n-1个数中找到最小(大)数与第二个数交换位置
    重复这样的操作...依次与第三个、第四个...数交换位置
    第n-1趟,最终可实现数据的升序(降序)排列。

    选择排序.png

    时间复杂度:选择排序的交换操作介于 0 和 (n - 1) 次之间。选择排序的比较操作为 n (n - 1) / 2 次之间。选择排序的赋值操作介于 0 和 3 (n - 1) 次之间

    2、冒泡排序

    2.冒泡排序将已排序部分定义在右端,在遍历未排序部分的过程执行交换,将最大元素交换到最右端。

    【冒泡排序】:相邻元素两两比较,比较完一趟,最值出现在末尾
    第1趟:依次比较相邻的两个数,不断交换(小数放前,大数放后)逐个推进,最值最后出现在第n个元素位置
    第2趟:依次比较相邻的两个数,不断交换(小数放前,大数放后)逐个推进,最值最后出现在第n-1个元素位置
    …… ……
    第n-1趟:依次比较相邻的两个数,不断交换(小数放前,大数放后)逐个推进,最值最后出现在第2个元素位置

    冒泡排序.png

    【平均时间复杂度:O(n^2) 平均空间复杂度:O(1) 】

    3、插入排序

    3.插入排序将已排序部分定义在左端,将未排序部分元的第一个元素插入到已排序部分合适的位置。

    从第一个元素开始,认为该元素已经是排好序的。
    取下一个元素,在已经排好序的元素序列中从后向前扫描。
    如果已经排好序的序列中元素大于新元素,则将该元素往右移动一个位置。
    重复步骤3,直到已排好序的元素小于或等于新元素。
    在当前位置插入新元素。
    重复步骤2。

    FF.png

    【平均时间复杂度:O(n^2) 平均空间复杂度:O(1)】

    4、快速排序

    快速排序(Quicksort)是对冒泡排序的一种改进。
    通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

    设置两个变量i、j,排序开始的时候:i=0,j=N-1;
    以第一个数组元素作为关键数据,赋值给key,即key=A[0];
    从j开始向前搜索,即由后开始向前搜索(j--),找到第一个小于key的值A[j],将A[j]和A[i]互换;
    从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于key的A[i],将A[i]和A[j]互换;
    重复第3、4步,直到i=j; (3,4步中,没找到符合条件的值,即3中A[j]不小于key,4中A[i]不大于key的时候改变j、i的值,使得j=j-1,i=i+1,直至找到为止。找到符合条件的值,进行交换的时候i, j指针位置不变。另外,i==j这一过程一定正好是i+或j-完成的时候,此时令循环结束)。

    EE.png

    最优情况下的时间复杂度 :O(logn) ;最差的情况下空间复杂度为:O( n ) ; 平均复杂度 O(nlogn)

    最优的情况下空间复杂度为:O(logn) ;最差的情况下空间复杂度为:O( n ) ;

    【平均时间复杂度:O(nlogn) 平均空间复杂度:O(nlogn) 】

    4.折半查找(二分查找)

    折半查找:优化查找时间(不用遍历全部数据)
    1、数组必须是有序的
    2、必须已知min和max(知道范围)
    3、动态计算mid的值,取出mid对应的值进行比较
    4、如果mid对应的值大于要查找的值,那么max要变小为mid-1
    5、如果mid对应的值小于要查找的值,那么min要变大为mid+1

    三、已知一个有序数组, 和一个key, 要求从数组中找到key对应的索引位置

    AA.png

    四、序数组合并

    将有序数组 {1,4,6,7,9} 和 {2,3,5,6,8,9,10,11,12} 合并为{1,2,3,4,5,6,6,7,8,9,9,10,11,12}

    BB.png

    五、在一个字符串中找到第一个只出现一次的字符。如输入"abaccdeff",输出'b'字符(char)是一个长度为8的数据类型,因此总共有256种可能。每个字母根据其ASCII码值作为数组下标对应数组种的一个数字。数组中存储的是每个字符出现的次数。

    CC.png

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

    分别记录两个子视图的所有父视图并保存到数组中,然后倒序寻找,直至找到第一个不一样的父视图

    DD.png

    七、字符串反转

    给定字符串 "hello,world",实现将其反转。输出结果:dlrow,olleh

    -(void)charReverse {
    
    NSString * string = @"hello,world";
    NSLog(@"%@",string);    
    
    NSMutableString * reverString = [NSMutableString stringWithString:string];
    for (NSInteger i = 0; i < (string.length + 1)/2; i++) {
        [reverString replaceCharactersInRange:NSMakeRange(i, 1) withString:[string substringWithRange:NSMakeRange(string.length - i - 1, 1)]];
        [reverString replaceCharactersInRange:NSMakeRange(string.length - i - 1, 1) withString:[string substringWithRange:NSMakeRange(i, 1)]];
    }
    NSLog(@"reverString:%@",reverString);
    
    //C
    char ch[100];
    memcpy(ch, [string cStringUsingEncoding:NSUTF8StringEncoding], [string length]);
    char * begin = ch;
    char * end = ch + strlen(ch) - 1;
    while (begin < end) {
        char temp = *begin;
        *(begin++) = *end;
        *(end--) = temp;
    }
    NSLog(@"reverseChar[]:%s",ch); 
    }

    相关文章

      网友评论

          本文标题:算法

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