輸入任意整數N,返回由相同數字組成的大於該整數N的最小整數, 比如,輸入15432 ,輸出 21345.
剛開始拿到這個題很懵,沒有什麼思路 , 最小的肯定是這些數字升序 -> 12345 , 最大的是這些數字降序排列 ->54321 , 至於中間的數字有什麼規律,確實沒有找到 ,索性 最差咱們還有枚舉法,總是能求出來的.
既然是枚舉類型,最常用的就是用for循環枚舉,但是這個比較特別,因爲這個N的位數是不確定的,看樣子只能用遞歸了.計算出一個結果後,還需要去掉本次計算痕跡, 這是最基礎的枚舉,後面可以利用這個枚舉做篩選排序,找出最小值.
- (void)viewDidLoad {
[super viewDidLoad];
NSArray * array = @[@1,@2,@3,@4,@5,];
[self getNumWithCurrent:0 WithLeftArray:array];
NSLog(@"self.resultArray.count : %lu",(unsigned long)self.resultArray.count);
}
/// 遞歸計算出一個數字
- (NSInteger)getNumWithCurrent:(NSInteger)currentNum WithLeftArray:(NSArray *)leftArray {
// 數組中沒有元素了,說明遍歷完成,返回當前值即可
if (leftArray.count==0) {
return currentNum;
}
// 遍歷剩餘的數組
for (NSNumber * num in leftArray) {
// 把currentNum*10 , 取出數組的元素,加到最後一位
currentNum *= 10;
currentNum += [num integerValue];
// 剩餘數組中移除選中的元素,進行下一次遞歸
NSMutableArray * next = [leftArray mutableCopy];
[next removeObjectAtIndex:[next indexOfObject:num]];
NSInteger result = [self getNumWithCurrent:currentNum WithLeftArray:next];
// 遞歸有了結果,保存結果
if (result != 0) {
NSLog(@"遞歸計算出結果:%@",@(result));
[self.resultArray addObject:@(result)];
}
// 回溯到初始位置,準備下一次的循環
currentNum -=[num integerValue];
currentNum /=10;
}
return 0;
}
- (NSMutableArray<NSNumber *> *)resultArray {
if (_resultArray == nil) {
_resultArray = [NSMutableArray array];
}
return _resultArray;
}
有了枚舉的方法 , 剩下的就簡單了, 核心在於枚舉方法,(遞歸+回溯)
1.把原始數字分解成NSNumber加入到數組
2.枚舉出所有的結果,把比原始數字大的加入到result數組
3.遍歷找出result數組中的最小值.
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic,strong) NSMutableArray<NSNumber *> * resultArray ;
@property (nonatomic,assign) NSInteger originalNum ;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self findBiggerNum:15432];
}
- (NSInteger)findBiggerNum:(NSInteger)oldNum {
_originalNum = oldNum ;
NSMutableArray * array = [NSMutableArray array];
while (oldNum>0) {
NSInteger temp = oldNum%10;
[array addObject:@(temp)];
oldNum = oldNum/10;
}
[self getNumWithCurrent:0 WithLeftArray:array];
NSLog(@"self.resultArray.count : %lu",(unsigned long)self.resultArray.count);
// 找出數組中的最小值
// NSInteger result = NSIntegerMax;
// for (NSNumber * temp in self.resultArray) {
// if (temp.integerValue<result) {
// result = temp.integerValue;
// }
// }
// 騷方法,找出最小值
NSInteger result = [[self.resultArray valueForKeyPath:@"@min.integerValue"] integerValue];
NSLog(@"找到了 : %@",@(result) );
return result;
}
/// 遞歸計算出一個數字
- (NSInteger)getNumWithCurrent:(NSInteger)currentNum WithLeftArray:(NSArray *)leftArray {
// 數組中沒有元素了,說明遍歷完成,返回當前值即可
if (leftArray.count==0) {
return currentNum;
}
// 遍歷剩餘的數組
for (NSNumber * num in leftArray) {
// 把currentNum*10 , 取出數組的元素,加到最後一位
currentNum *= 10;
currentNum += [num integerValue];
// 剩餘數組中移除選中的元素,進行下一次遞歸
NSMutableArray * next = [leftArray mutableCopy];
[next removeObjectAtIndex:[next indexOfObject:num]];
NSInteger result = [self getNumWithCurrent:currentNum WithLeftArray:next];
// 遞歸有了結果,保存結果
if (result != 0) {
NSLog(@"遞歸計算出結果:%@",@(result));
if (result>_originalNum) {
[self.resultArray addObject:@(result)];
}
}
// 回溯到初始位置,準備下一次的循環
currentNum -=[num integerValue];
currentNum /=10;
}
return 0;
}
- (NSMutableArray<NSNumber *> *)resultArray {
if (_resultArray == nil) {
_resultArray = [NSMutableArray array];
}
return _resultArray;
}
@end