[算法图解]笔记,递归
DC解决问题两个步骤
- 找出基线条件,条件尽量简单
- 不断将问题分解,直到符合基线条件
分割土地基线条件:
- 一条边是另外一条边的整数倍
问题:如何将矩形均匀的分成方块,确保分出的方块最大,(求构成一个矩形的最大正方形)==>求出矩形的最小元素的宽度
var result = this.rectMaxWidth(1680,640) console.log("结果:" + result) // test rectMaxWidth: function (x, y) { if (x > y) { } else { var temp = x x = y y = temp } if (x % y == 0) { return y } else { var x = x - y return this.rectMaxWidth(x, y) } },
递归求和
给定一个数组,求数组中所有元素的和
// 给定数组,求数组所有元素的和 sumArr:function(array) { var length = array.length if(length == 0){ return 0 } else { // 数组排除掉第一个元素得到后面的数组 return array[0] + this.sumArr(array.slice(1)) } },
求数组中最大的元素
maxItem:function(sourceArr) { if(sourceArr.length == 2){ //最小规模的问题 var firstItem = sourceArr[0] var secondItem = sourceArr[1] if (firstItem > secondItem){ return firstItem }else { return secondItem } }else if(sourceArr.length == 1) { return sourceArr[0] } else { //缩小规模 // 3个 切割比较第一个跟后面的结果 var subArr = sourceArr.slice(1) var subResult = this.maxItem(subArr) var newArr = [sourceArr[0],subResult] return this.maxItem(newArr) } }
找出二分查找的基线条件(最小规模的问题)和递归条件(缩小问题)
二分查找找到最大的数
基线条件: 如果只有两个元素,直接比较大小,返回大的元素
如果超出两个元素,将数组在中间切割成两部分,两个数组
递归条件:中间切割数组,变成两个数组,缩小规模
- (NSInteger)middleCutMax:(NSArray *)sourceArr { if(sourceArr.count == 2){ NSNumber *first = sourceArr[0]; NSInteger firstInt = first.integerValue; NSNumber *second = sourceArr[1]; NSInteger secondInt = second.integerValue; if (firstInt > secondInt) { return firstInt; }else { return secondInt; } }else if(sourceArr.count == 1){ NSNumber *only = sourceArr[0]; return only.integerValue; }else { NSInteger subIdx = sourceArr.count / 2; NSRange range1 = NSMakeRange(0, subIdx); NSInteger length = sourceArr.count - (subIdx ); NSRange range2 = NSMakeRange(subIdx, length); NSArray *arr1 = [sourceArr subarrayWithRange:range1]; NSArray *arr2 = [sourceArr subarrayWithRange:range2]; NSLog(@"切割结果钱:%@---后:%@",arr1,arr2); NSInteger leftMax = [self middleCutMax:arr1]; NSInteger rightMax = [self middleCutMax:arr2]; NSNumber * leftnum = [NSNumber numberWithInteger:leftMax]; NSNumber *rightNum = [NSNumber numberWithInteger:rightMax]; NSArray *arrayNew = @[leftnum,rightNum]; return [self middleCutMax:arrayNew]; } }
二分查找,快速找到目标数字
基线条件:数组中只有一个元素,判断要找的元素跟数组中的元素是否相等,相等的话,找到了,不相等,就不在里面
递归条件(缩小问题规模):多余一个元素的数组,从中间切割成两个数组,判断这两个数组中是否有目标数字
- (BOOL)arrayHasNum:(NSInteger)number array:(NSArray *)sourceArr { if (sourceArr.count == 1) { NSNumber *item = sourceArr[0]; if (item.integerValue == number) { return YES; }else { return NO; } }else if (sourceArr.count == 0){ return NO; }else {// 2个,中间分隔 NSInteger middleIdx = sourceArr.count / 2; NSArray *leftArr = [sourceArr subarrayWithRange:NSMakeRange(0, middleIdx)]; NSArray *rightArr = [sourceArr subarrayWithRange:NSMakeRange(middleIdx, sourceArr.count - middleIdx)]; BOOL inLeft = [self arrayHasNum:number array:leftArr]; if (inLeft) { return YES; }else { BOOL inRight = [self arrayHasNum:number array:rightArr]; if (inRight) { return YES; }else { return [self arrayHasNum:number array:rightArr]; } } } }
快速排序:
//快速排序
- (NSArray *)quickSortSourceArr:(NSArray <NSNumber *>*)sourceArr { if (sourceArr.count == 0) { return @[]; }else if (sourceArr.count == 1){ return sourceArr; }else if (sourceArr.count == 2) { NSNumber *first = sourceArr[0]; NSNumber *second = sourceArr[1]; if (first.integerValue > second.integerValue) { return @[second,first]; }else { return sourceArr; } }else { // 3个元素 NSNumber *position = sourceArr[sourceArr.count - 1]; //最后一个元素 NSArray *subArr = [sourceArr subarrayWithRange:NSMakeRange(0, sourceArr.count - 1)]; NSMutableArray *smallArr = [NSMutableArray array]; NSMutableArray *bigArr = [NSMutableArray array]; for (NSInteger i = 0; i < subArr.count; i++) { NSNumber *item = subArr[i]; if (item.integerValue > position.integerValue) { [bigArr addObject:item]; }else { [smallArr addObject:item]; } } // 对左右两个数组排序 NSArray *leftResult = [self quickSortSourceArr:smallArr]; NSArray *rightResult = [self quickSortSourceArr:bigArr]; NSMutableArray *result = [NSMutableArray array]; for (NSInteger i = 0 ; i < leftResult.count; i++) { [result addObject:leftResult[i]]; } [result addObject:position]; for (NSInteger i = 0; i < rightResult.count; i++) { [result addObject:rightResult[i]]; } return result; } }