这是一个猎头发来的算法题,写了4个小时终于写完了。
#import "ViewController.h"
@interface ViewController ()
//存放所有的排列组合的数组
@property (nonatomic, strong) NSMutableArray *allSorts;
//存放符合要求的组合的数组
@property (nonatomic, strong) NSMutableArray *result;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
/*
start = "hlt"
end = "cag"
dict = ["hat","dat","dag","lat","lag"]
[
["hlt","hat","dat","dag","cag"],
["hlt","hat","lat","lag","cag"]
]
•每次只有一个字母可以被改变
•每个中间词必须存在于词典
所有字具有相同的长度。
所有关键词只包含小写字母。
*/
NSMutableArray *dicList = [NSMutableArray arrayWithArray:@[@"hat",@"dat",@"dag",@"lat",@"lag"]];
//调用了这个方法后,result数组中会存储所有符合条件数组。
[self findPathWithStar:@"hlt" End:@"cag" dicList:dicList];
if (self.result.count > 0) {
NSLog(@"%@",self.result);
} else {
NSLog(@"没有符合条件的组合");
}
}
#pragma mark: 执行此方法
- (void)findPathWithStar:(NSString *)start End:(NSString *)end dicList:(NSMutableArray *)list {
if (![self checkWordISLowercase:start End:end dicList:list]) {
NSLog(@"单词必须全是小写,请重新输入");
return;
}
if (start.length == end.length) {
for (NSString *word in list) {
if (word.length != start.length) {
//长度必须全部相同。
NSLog(@"长度必须相同");
return;
}
}
}
//获取所有的排列组合
[self allSortsWithList:list Start:0 End:list.count - 1];
for (NSMutableArray *arr in self.allSorts) {
//首尾替换成 start 和 end
[arr replaceObjectAtIndex:0 withObject:start];
[arr replaceObjectAtIndex:arr.count - 1 withObject:end];
//比较相邻的连个单词,并保存符合条件的数组
[self compareClosestWord:arr];
}
//去除重复的数组
[self removeRepeatArr:self.result];
}
//检查所有单词是否全是小写
- (BOOL)checkWordISLowercase:(NSString *)start End:(NSString *)end dicList:(NSArray *)list {
if ([self wordIsLowerCase:start] && [self wordIsLowerCase:end]) {
for (NSString *word in list) {
if (![self wordIsLowerCase:word]) {
//NSLog(@"第一个不符合标准的单词:%@", word);
return false;
}
}
//NSLog(@"全是小写,符合条件");
return true;
}
return false;
}
//检查单词是否全是小写
- (BOOL)wordIsLowerCase:(NSString *)word {
for (int i=0; i char c = [word characterAtIndex:i]; if (c < 'a' || c > 'z') { NSLog(@"单词不全是小写字母,返回False"); return false; } } return true; } //获取所有的排列组合 - (void)allSortsWithList:(NSMutableArray *)list Start:(NSInteger)start End:(NSInteger)end { if (start == end) { // 为新的排列组合创建一个数组容器 NSMutableArray *newArr = [NSMutableArray arrayWithCapacity:list.count]; for (int i=0; i<=end; i++) { newArr[i] = list[i]; } // 将新的排列组合存放起来 [self.allSorts addObject:newArr]; } else { for (NSInteger i = start; i<=end; i++) { // 交换数组第一个元素与后续的元素 NSString *tempStr = list[start]; list[start] = list[i]; list[i] = tempStr; // 后续元素递归全排列 [self allSortsWithList:list Start:start + 1 End:end]; // 将交换后的数组还原 list[i] = list[start]; list[start] = tempStr; } } } //比较数组中相邻的连个单词,若全都只有一个字母不同,那么保存此数组 - (void)compareClosestWord:(NSArray *)arr { for (int i=0; i NSString *firstWord = arr[i]; NSString *secondeWord = arr[i+1]; //记录有几个字母不同 NSInteger diffCount = 0; for (int i = 0; i NSString *c1 = [firstWord substringWithRange:NSMakeRange(i, 1)]; NSString *c2 = [secondeWord substringWithRange:NSMakeRange(i, 1)]; if (c1 != c2) { diffCount++; if (diffCount >= 2) { return; } } } } [self.result addObject:arr]; } //去除 result 中重复的数组 - (void)removeRepeatArr:(NSMutableArray *)arr { if (arr.count < 2) { //当 result 中的元素个数小于 2 个时,直接return return; } //这里用C语言数组更简单,但是声明C语言数组时必须指定长度,如果不指定长度,程序会莫名的崩掉 NSMutableArray *indexArr = [NSMutableArray array]; //比较出重复的数组,记录下标 for (NSInteger i=0; i for (NSInteger j=i+1; j if ([self isEqualArr1:arr[i] Arr2:arr[j]]) { [indexArr addObject:@(j)]; } } } //给index数组降序排序 for (NSInteger i=0; i for (NSInteger j=i+1; j NSInteger m = [indexArr[i] intValue]; NSInteger n = [indexArr[j] intValue]; if (m < n) { [indexArr replaceObjectAtIndex:i withObject:@(n)]; [indexArr replaceObjectAtIndex:j withObject:@(m)]; } } } //从后往前,移除重复元素 for (NSInteger i=0; i [arr removeObjectAtIndex:[indexArr[i] intValue]]; } } //比较两个数组中的元素是否相同(元素相同,元素排列顺序也相同) - (BOOL)isEqualArr1:(NSArray *)arr1 Arr2:(NSArray *)arr2 { if (arr1.count != arr2.count) { return false; } for (int i=0; i if (arr1[i] != arr2[i]) { return false; } } return true; } //懒加载创建存放所有排列组合的数组 - (NSMutableArray *)allSorts { if (!_allSorts) { _allSorts = [NSMutableArray array]; } return _allSorts; } - (NSMutableArray *)result { if (!_result) { _result = [NSMutableArray array]; } return _result; } @end