找出给定数组中和是给定目标整数的两个整数,输出找到的两个整数下标。


(本文获得CSDN质量评分【90】)


【学习的细节是欢悦的历程】


  • Python 官网:https://www.python.org/

  • Free:大咖免费“圣经”教程《 python 完全自学教程》,不仅仅是基础那么简单……


  自学并不是什么神秘的东西,一个人一辈子自学的时间总是比在学校学习的时间长,没有老师的时候总是比有老师的时候多。
            —— 华罗庚


  • My CSDN主页、My HOT博、My Python 学习个人备忘录
  • 好文力荐、 老齐教室



找出给定数组中和是给定目标整数的两个整数 两数之和 (输出找到的两个整数下标)



本文质量分:

90 】 本文地址: https://blog.csdn.net/m0_57158496/article/details/128608287

CSDN质量分查询入口:http://www.csdn.net/qc


目 录

  • ◆ 两数之和
    • 1、题目
      • 1.1 题目描述
      • 1.2 输入输出示例
      • 1.3 代码运行效果截屏
    • 2、两层for循环的常规算法
      • 2.1 能实现代码
      • 2.2 优化代码
    • 3、用enumerate秀一下常规算法
    • 4、借助dict一次遍历的优化算法
    • 5、代码试炼——结果输出
    • 6、完整源码

◆ 两数之和


回页目录


1、题目

1.1 题目描述

  给定一个整数数组nums和一个整数目标值target,请你在该数组中找出和为目标值target的那两个整数,并返回它们的数组下标。
  你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
  你可以按任意顺序返回答案。

1.2 输入输出示例

输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。

输入:nums = [3,2,4], target = 6
输出:[1,2]

输入:nums = [3,3], target = 6
输出:[0,1]

输入:nums = [2, 7, 3, 8, 43, 12, 15, 5], target = 13
输出:[3, 7]

1.3 代码运行效果截屏

  用两个整数(和为target的两个整数)在数组最后也就是最坏情况试炼。

能实现代码:

优化代码

优化算法代码:

  显而易见,算法优化的效果,更显著于代码优化。


回页目录


2、两层for循环的常规算法

  一般运用两层遍历,常规算法。用数组中的每一个数和数组中的数依次试炼,查找符题的两个整数下标。

2.1 能实现代码

  题目中说明,nums有且仅有一组两数和等于target。所以当找到后,就可以return直接返回两数下标,结束遍历工作。


def sum_two_number(nums, target):''' 输出nums中两数和为target的下标 '''n = len(nums)for i in range(n):for j in range(1, n):if nums[i] + nums[j] == target and i != j:return [i, j] # 题目中说明,nums有且仅有一组两数和等于target。所以找到后就可以直接返回两数下标,结束遍历工作。

2.2 优化代码

  第二层for循环,只遍历i后的整数即可(从i+1开始遍历),i前的整数已经遍历过,重复遍历就是空耗浪费。


def sum_two_number(nums, target):''' 输出nums中两数和为target的下标 '''n = len(nums)for i in range(n):for j in range(i+1, n): # 只遍历i后的整数,i前的整数已经遍历。if nums[i] + nums[j] == target and i != j:return [i, j] # 题目中说明,nums有且仅有一组两数和等于target。所以找到后就可以直接返回两数下标,结束遍历工作。

回页目录


3、用enumerate秀一下常规算法

   enumerate,Python内建枚举函数,可以以元组 (tuple,(下标, 元素))的形式同时遍历数组的元素和下标。


def sum_two_number5(nums, target):''' 输出nums中两数和为target的下标 '''n = len(nums)k = 0for i in enumerate(nums):for j in enumerate(nums):k += 1if not j[0] > i[0]:continue # 第一层for遍历过的整数,直接跳过。if i[1] + j[1] == target:print(f"\n{'':>17}程序遍历了{k}次。\n{'':~^50}\n")return [i[0], j[0]] # 题目中说明,nums有且仅有一组两数和等于target。所以找到后就可以直接返回两数下标,结束遍历工作。

  也可以把“第二层for遍历循环用if直接跳过 (continue)已遍历过的整数”,用条件判断语句 (j != i ,比较遍历到的整数(下标和元素),相同于上层for遍历循环,即是已操作过的整数)连接 (and)在下一个if一起判断。


def sum_two_number(nums, target):''' 输出nums中两数和为target的下标 '''n = len(nums)k = 0for i in enumerate(nums):for j in enumerate(nums):k += 1if i[1] + j[1] == target and j != i:print(f"\n{'':>17}程序遍历了{k}次。\n{'':~^50}\n")return [i[0], j[0]] # 题目中说明,nums有且仅有一组两数和等于target。所以找到后就可以直接返回两数下标,结束遍历工作。

  以上两段代码,完全等效。


回页目录


4、借助dict一次遍历的优化算法

  借助Python的字典dict,实现一次for遍历的优化算法。
  题目中说明“有且仅有”一组符合要求的两个整数,把当前遍历的整数作为第一个数,另一个整数即是target-nums[i]。在字典nums_index中查找另一个整数,如果没有,将当前遍历的整数追加到字典,因为当前整数可能是“另一个”整数。
  这样子,最坏情况也就是遍历到数组最后一个整数,也就是是遍历n次(n=len(nums))


def sum_two_number(nums, target):''' 输出nums中两数和为target的下标 '''nums_index = {} # 初始化整数-下标字典。for i in range(len(nums)):# 当前下标对应整数与目标整数的差值(即第二个整数),不在字典nums_index中,将当前整数以(整数, 下标)键值对放入字典。if target - nums[i] not in nums_index:nums_index[nums[i]] = i#print(nums_index) 调试用语句。else: # 如果当前下标对应整数与目标整数差值在字典nums_index中,即找到第二个整数。返回字典中差值为key的value(下标)和当前下标。return [nums_index.get(target - nums[i]), i]

回页目录


5、代码试炼——结果输出

  除了题目中的数组,还增加了一个“最坏情况”数组试炼。加入k变量计算遍历次数,就得到了本文开头的代码运行效果截屏图片(可点击蓝色文字跳转),查看代码运行效果截屏图片。


# 结果输出。
if __name__ == '__main__':nums, target = [2, 7, 11, 15], 9nums, target = [3, 2, 4], 6nums, target = [3, 3], 6nums, target = [2, 7, 3, 43, 12, 15, 5, 8], 13s = '给定一个整数数组nums和一个整数目标值target,请你在该数组中找出和为目标值target的那两个整数,并返回它们的数组下标。'print(f"\n{' 两数之和 ':=^46}\n\n{'':>4}{s}\n{'':~^50}\n\n\n{'':>2}nums = {nums}, target = {target}\n{'':~^50}")result = f"{'':>18}result = {sum_two_number(nums, target)}\n\n{'':=^50}\n"print(result)

回页目录


6、完整源码

(源码较长,点此跳过源码)

#!/sur/bin/nve python
# coding: utf-8# 一、两层遍历,常规算法。
def sum_two_number(nums, target):''' 输出nums中两数和为target的下标 '''n = len(nums)k = 0for i in range(n):for j in range(i+1, n): # 只遍历i后的整数,i前的整数已经遍历。k += 1if nums[i] + nums[j] == target:print(f"\n{'':>17}程序遍历了{k}次。\n{'':~^50}\n")return [i, j] # 题目中说明,nums有且仅有一组两数和等于target。所以找到后就可以直接返回两数下标,结束遍历工作。def sum_two_number5(nums, target):''' 输出nums中两数和为target的下标 '''n = len(nums)k = 0for i in enumerate(nums):for j in enumerate(nums):k += 1if not j[0] > i[0]:continue # 第一层for遍历过的整数,直接跳过。if i[1] + j[1] == target:print(f"\n{'':>17}程序遍历了{k}次。\n{'':~^50}\n")return [i[0], j[0]] # 题目中说明,nums有且仅有一组两数和等于target。所以找到后就可以直接返回两数下标,结束遍历工作。def sum_two_number(nums, target):''' 输出nums中两数和为target的下标 '''n = len(nums)k = 0for i in enumerate(nums):for j in enumerate(nums):k += 1if i[1] + j[1] == target and j != i:print(f"\n{'':>17}程序遍历了{k}次。\n{'':~^50}\n")return [i[0], j[0]] # 题目中说明,nums有且仅有一组两数和等于target。所以找到后就可以直接返回两数下标,结束遍历工作。# 二、借助dict,一次遍历。
def sum_two_number2(nums, target):''' 输出nums中两数和为target的下标 '''nums_index = {} # 初始化整数-下标字典。k = 0 # 初始遍历次数。for i in range(len(nums)):# 当前下标对应整数与目标整数的差值(即第二个整数),不在字典nums_index中,将当前整数以(整数, 下标)键值对放入字典。if target - nums[i] not in nums_index:nums_index[nums[i]] = ik += 1#print(nums_index) 调试用语句。else: # 如果当前下标对应整数与目标整数差值在字典nums_index中,即找到第二个整数。返回字典中差值为key的value(下标)和当前下标。print(f"\n{'':>17}程序遍历了{k+1}次。\n{'':~^50}\n")return [nums_index.get(target - nums[i]), i]'''
结果输出。
我共用输出语句,想看哪个哪个函数输出效果,将写在她后面的函数名称后加个字符,不让其覆盖她(重置、重写)就好。
'''
if __name__ == '__main__':nums, target = [2, 7, 11, 15], 9nums, target = [3, 2, 4], 6nums, target = [3, 3], 6nums, target = [2, 7, 3, 43, 12, 15, 5, 8], 13s = '给定一个整数数组nums和一个整数目标值target,请你在该数组中找出和为目标值target的那两个整数,并返回它们的数组下标。'print(f"\n{' 两数之和 ':=^46}\n\n{'':>4}{s}\n{'':~^50}\n\n\n{'':>2}nums = {nums}, target = {target}\n{'':~^50}")result = f"{'':>18}result = {sum_two_number(nums, target)}\n\n{'':=^50}\n"print(result)

回页首


__上一篇:__ 列表(list)的7种实现方式

__下一篇:__ 


我的HOT博: