1. 两数之和

 

 

方法一:暴力枚举

 

思路及算法:

枚举数组中的每一个数X,寻找数组中是否存在target - X。当使用遍历整个数组的方式寻找 target – X 时,需要注意到每一个位于 X 之前的元素都已经和 X 匹配过,因此不需要再进行匹配。而每一个元素不能被使用两次,所以我们只需要在X后面的元素中寻找target - X。

 

代码:

 1 C:
 2 /**
 3  * Note: The returned array must be malloced, assume caller calls free().
 4  * 这句话的意思就是新建数组时需要使用malloc函数。
 5  */
 6 int* twoSum(int* nums, int numsSize, int target, int* returnSize) {
 7     for (int i = 0; i < numsSize; ++i) {
 8         for (int j = i + 1; j < numsSize; ++j) {
 9             if (nums[i] + nums[j] == target) {
10                 int* ret = malloc(sizeof(int) * 2);
11                 ret[0] = i, ret[1] = j;
12                 *returnSize = 2;
13                 return ret;
14             }
15         }
16     }
17     *returnSize = 0;
18     return NULL;
19 }

复杂度分析:

  • 时间复杂度:,其中N是数组中的元素数量。最坏情况下数组中任意两个数都要被匹配一次。
  • 空间复杂度:。

 

提交结果:

上述暴力枚举代码只能通过78/80的测试用例,提交结果是运行超时,原因在于时间复杂度较高。

 

方法二:哈希表

 

思路及算法:

在遍历的同时,记录一些信息,省去一层循环,以“空间换时间”。需要记录遍历过的数值和它对应的下标,可以通过查找表实现。一种是哈希表,一种是平衡二叉树(需要维护元素的顺序)。

 

从头开始遍历,目标值是8,第一个数是6,需要寻找2,不在哈希表中,将6放入哈希表中,遍历下一个数。第二个数是3,需要寻找5,不在哈希表中,将3放入哈希表中,遍历下一个数。第三个数是8,需要寻找0,不在哈希表中,将8放入哈希表中,遍历下一个数。第四个数是2,需要寻找6,在哈希表中,将6的下标与2的下标输出。

 

代码:

 1 Java:
 2 class Solution {
 3     public int[] twoSum(int[] nums, int target) {
 4         //设置hash表长度
 5         int len = nums.length;
 6         //定义hash表
 7         Map<Integer, Integer> hashtable = new HashMap<Integer, Integer>(len-1);
 8         //将第一个直接放入hash表中
 9         hashtable.put(nums[0] , 0 );
10         for (int i = 1; i < nums.length; i++) {
11             //判断hash表中是否已存在符合输入条件的数
12             if (hashtable.containsKey(target - nums[i])) {
13                 return new int[]{hashtable.get(target - nums[i]) , i};
14             }
15             //没有找到,就插入hash表中
16             hashtable.put(nums[i], i);
17         }
18         return new int[0];
19     }
20 }

复杂度分析:

  • 时间复杂度:,其中N是数组中的元素数量。
  • 空间复杂度:。哈希表中最多需要存n-1个键值对。

 

提交结果:

 

posted @ 2020-11-17 20:20  北漂的尘埃  阅读(130)  评论(0编辑  收藏  举报