LeetCode -- TwoSum

题目:

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;
        }

猜你喜欢

转载自blog.csdn.net/iO_O_Oi/article/details/92389937