算法1:给定一个整数数组和一个目标值,找出数组中和为目标值的两个数的index值。

三种解决方法:
1、暴力法:遍历每个num,查找目标元素target-num

 class Solution:
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        n = len(nums)
        for i in range(0,n):
            for j in range(i+1,n):
                if nums[j] == target - nums[i]:
                    return [i,j]

nums = [2, 7, 11, 15]
target = 9
twoSumExp = Solution()
print(twoSumExp.twoSum(nums, target))   

时间复杂度:O(n2),其中,对于每个num,查找目标元素target-num的复杂度为O(n)
空间复杂度:O(1)
2、两次哈希表法:第一次循环,创建数组中值和索引的字典;第二次循环,从字典中找出target-num对应值。

class Solution:
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        numsDict = {}
        n = len(nums)
        for i in range(0,n):
            numsDict[nums[i]] = i
        for j in range(0,1):
            num2 = target - nums[j]
            if  num2 in nums and numsDict.get(num2)!=j:
                return [j,numsDict[num2]]

nums = [2, 7, 11, 15]
target = 9
twoSumExp = Solution()
print(twoSumExp.twoSum(nums, target))

时间复杂度:O(n),虽然也将列表遍历了两遍,但是字典的查找时间为O(1)
空间复杂度:O(n),创建了一个哈希表
降低了时间复杂度,增加了空间复杂度
3.一次哈希表法:在创建数组中值和索引的字典时,返回去检查是否存在当前元素所对应的元素。

class Solution:
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        numsDict = {}
        n = len(nums)
        for i in range(0,n):
            numsDict[nums[i]] = i
            j = numsDict.get(target - nums[i],-1)
            if j != -1 and j != i:
                return [j,i]

nums = [2, 7, 11, 15]
target = 9
twoSumExp = Solution()
print(twoSumExp.twoSum(nums, target))

时间复杂度:O(n),遍历加查找一次
空间复杂度:O(n),创建一个哈希表

补充知识:算法复杂度*
算法复杂度包括时间复杂度空间复杂度
1.算法的时间复杂度
(1)定义:时间复杂度是指执行算法所需要的计算工作量。一般,算法的工作量用其执行的基本运算次数来度量,而算法执行的基本运算次数是问题规模的函数。
(2)在同一个问题规模下,用平均性态最坏情况来分析。一般情况下,用最坏情况的复杂度来分析算法的时间复杂度。
(3)几种常见时间复杂度
[1]常数阶运行次数与问题规模无关,执行时间恒定的算法,称为O(1)时间复杂度。一般顺序结构单纯的分支结构(如if语句,不论真或假)执行次数不会随问题规模变化,时间复杂度是O(1);
[2]线性阶:确定某个算法的阶次,需确定某个特定语句或某个特定语句块运行的次数。算法的阶次的确定主要关注循环结构的运行情况。一般情况下,当单个for循环中循环条件与问题规模有关时,其时间复杂度为O(n)
[3]平方阶:当嵌套的两个for 循环中循环条件都与问题规模有关时,时间复杂度为O(2)。
如果外循环的循环次数改为m,则时间复杂度为O(m*n)。
即,循环的时间复杂度等于循环体的复杂度乘以该循环运行的次数。
[4]立方阶:与线性阶或平方阶类似,立方阶一般出现在三个for循环嵌套的循环中。但是,三个for循环嵌套,算法的复杂度不一定为O(3)。
[5]对数阶:时间复杂度为O( logn)
如下例,num乘上多少个2后能大于n,即2**x = n,则x = logn

num = 1
while num < n:
    num *= 2

常用时间复杂度所耗费的时间从大到小:
O(n**2)>O(nlogn)>O(n)>O(logn)>O(1)
(4)举例说明:

for i in range(n):
    for j in range(i,n):
        pass

分析:当i=0时,内循环次数为n;当n=1时,内循环次数为n-1;…当n=n-1时,内循环次数为1.
则运行总次数为n +(n-1)+(n-2)+….1=(n(n+1))/2=(n^2/2)+n/2
只保留最高项;不考虑乘除因子
则,该算法的复杂度为O(2)

2.算法的空间复杂度
(1)定义:空间复杂度是指执行这个算法所需要的内存空间
(2)一般,可以创建一个新的辅助存储结构,通过牺牲空间复杂度来换取时间复杂度。
(3) 一般情况下,执行程序时,除了需要存储程序本身的指令、常数、变量和输入数据外,还需要存储对数据操作的存储单元。若输入数据所占空间只取决于问题本身,和算法无关,这样只需要分析该算法在实现时所需的辅助单元即可。若算法执行时所需的辅助空间相对于输入数据量是个常数,则称此算法的空间复杂度为0(1)。

                    欢迎批评指正!!!

你可能感兴趣的:(算法1:给定一个整数数组和一个目标值,找出数组中和为目标值的两个数的index值。)