题目:
Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9, Because nums[0] + nums[1] = 2 + 7 = 9, return [0, 1].题目分析:
1、给定一个目标值target,在数组中找两个数相加为此值。
2、是数组中2个不同index的数( you may not use the same element twice)
3、数组中的数字可能会有重复,或者多解,返回其中一个解即可
一般的处理方式,时间复杂度和那个冒泡排序差不多,:
public static int[] Solution1(int[] nums, int target)
{
int[] resArr = new int[2];
//一般思路
int subNum = 0;
for (int i = 0; i < nums.Length; i++)
{
subNum = target - nums[i];
for (int j=i+1; j<nums.Length; j++)
{
if (subNum == nums[j])
{
resArr[0] = i;
resArr[1] = j;
return resArr;
}
}
}
return resArr;
}
思考:如何提高速度?有一个亘古不变的原则,减少时间复杂度势必会增加空间复杂度(内存消耗)。反过来说,通过消耗一定的内存(缓存一些数据),可以有效提高计算速度。如何设计一个数据结构,缓存在第一次遍历时能够获取的有用信息?
public static int[] Solution2(int[] nums, int target)
{
int[] resArr = new int[2];
Dictionary<int, int> dicNums = new Dictionary<int, int>();
int subNum = 0;
for (int i = 0; i < nums.Length; i++)
{
subNum = target - nums[i];
if (dicNums.ContainsKey(subNum)) //利用字典key的特性,增加查找速度
{
resArr[0] = dicNums[subNum];
resArr[1] = i;
break;
}
else if (dicNums.ContainsKey(nums[i]))
continue;
else
dicNums.Add(nums[i], i); //缓存坐标信息
}
return resArr;
}
1、通过一个字典,记录其值和坐标的信息,这样就可以避免坐标寻找的遍历。
2、差值来进行查找
当然,我们也可以保存差值和坐标信息来实现,基本和上面是等价的:
public static int[] Solution3(int[] nums, int target)
{
int[] resArr = new int[2];
//追求时间的快速,那就消耗内存吧
//在第一次遍历的时候尽可能的存储有用信息
//设计一种数据结构,在第一次遍历的时候填充信息,最好直接记录坐标,避免第二次遍历 使时间复杂度下降到 O(n)
//核心问题:如何记录坐标
//[2,8,7,4,8] 9
//[7,1,2,5,1]
Dictionary<int, int> dicNums = new Dictionary<int, int>();
int subNum = 0;
for (int i=0; i<nums.Length; i++)
{
subNum = target - nums[i];
if (dicNums.ContainsKey(nums[i]))
{
resArr[0] = dicNums[nums[i]];
resArr[1] = i;
break;
}
else if(dicNums.ContainsKey(subNum))
{
continue;
}
else
{
dicNums.Add(subNum,i);
}
}
return resArr;
}