【iOS每日算法】两数之和:给定一个整数数组,和一个目标值,找出数组中和为目标值的两个整数

题目:

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/two-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

考察点:

  • 这是一道LeetCode上非常基础的一道算法题。主要考察的就是哈希表查找对应键值的时间复杂度O(1)。

解法:

一、暴力循环
  • 循环数组中每一个数字和之后的数字做比较,若两者和为目标数值return两个数字的index
  • 时间复杂度O(n²)

  - (NSArray *)twoSums:(NSArray *)numArray equalTo: (int) total {
    for (int i = 0; i < numArray.count; i++) {
        for (int j = i + 1; j < numArray.count; j++) {
            int q = [numArray[i] intValue];
            int w = [numArray[j] intValue];
            if(q + w == total) {
                return @[@(i), @(j)];
            }
        }
    }
    return nil;
}

二、使用哈希表
  • 在循环数组将值插入表中的同时,查找哈希表中是否含有目标值减去当前值的key。如果存在将其立即返回
  • 时间复杂度:O(n),因为我们只遍历了包含有 n 个元素的列表一次。在表中进行的每次查找只花费 O(1) 的时间。这样就降低了算法的时间复杂度
  • NSDictionary底层就是哈希表所以这里我们用NSDictionary代替
- (NSArray *)dictTwoSums:(NSArray *)numArray equalTo: (int) total {
    NSMutableDictionary *usedNums = [NSMutableDictionary dictionaryWithCapacity:numArray.count];
    for (int i = 0; i < numArray.count; i++) {
        int q = [numArray[i] intValue];
        NSNumber *w = [NSNumber numberWithInt:(total - q)];
        if([[usedNums allKeys]containsObject:w]) {
            return @[@(i), [usedNums objectForKey:w]];
        } else {
            [usedNums setObject:@(i) forKey:numArray[i]];
        }
    }
    return nil;
}

总结

  • 这道题让我了解并熟悉了哈希表,理解了这个算法对你之后编程的思路的思考有很大帮助
  • 如果想要了解更多hash表、NSDictionary的相关知识可以看这篇文章,我觉得写的还是很不错的
    https://www.jianshu.com/p/0d7cd6341f65

思考

  • 这两个算法写完思路虽然比原来扩展了,但这两个方法执行起来的时间,不管数组长短,元素位置变化,总是第一个方法实现的时间更短。背后的原因是因为NSDictionary的相关方法增加了开销,还是其他原因,值得思考。

你可能感兴趣的:(【iOS每日算法】两数之和:给定一个整数数组,和一个目标值,找出数组中和为目标值的两个整数)