算法

一、交换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趟,最终可实现数据的升序(降序)排列。

算法_第1张图片
选择排序.png

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

2、冒泡排序

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

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

算法_第2张图片
冒泡排序.png

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

3、插入排序

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

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

算法_第3张图片
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-完成的时候,此时令循环结束)。

算法_第4张图片
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对应的索引位置

算法_第5张图片
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}

算法_第6张图片
BB.png

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

算法_第7张图片
CC.png

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

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

算法_第8张图片
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); 
}

你可能感兴趣的:(算法)