Python每日一练-----妈妈找小蝌蚪(进阶版),指针的灵活运用
题目:
给定一个池塘里面有众多小蝌蚪(整数数组 nums) 他们已经排队好了,有一位青蛙妈妈(一个目标值 :0),请你帮助青蛙妈妈找到他的亲生孩子(青蛙:生的时候我也没想过要找啊),假设青蛙妈妈身上带有一个整数mom,池塘中每个小蝌蚪身上各有一个整数(有的小蝌蚪拥有一样的数),生活压力太大了,最近得以改善,所以青蛙妈妈这次把自己的娃都找到,且每次找三个组成一组,一组一组找知道找完,一组亲生娃身上所带的整数相加正好等于青蛙妈妈身上的整数mom。
例1
池塘中所有小蝌蚪所带整数构成的数组为: nums = [-4, 5, 2, -1]
青蛙妈妈的目标值为:mom = 0
你需要找出一组娃(三个)个娃:-4,5,-1
返回:[[-4, 5, -1]]
例2
众多小蝌蚪所带整数构成的数组为: nums = [-1, 3, -2, 1,0]
青蛙妈妈的目标值为:mom = 0
你需要找出一组娃(三个)个娃:-1,3,-2和-1,1,0
返回:[[-1,3,-2],[-1,1,0]]
例3
众多小蝌蚪所带整数构成的数组为: nums = [1, 3, -9, 1,0]
青蛙妈妈的目标值为:mom = 0
你需要找出一组娃(三个)个娃:无(没有亲生娃)
返回:[]
注:返回的列表不能含有相同的子列表
题目分析:给定一个数组nums,要求找出三个数相加为0,并找出所有结果。
老样子,按平常思路
暴力解题:
从数组中一个一个找出第一第二第三个孩子,将其所带整数相加看是否为0
假设三个小蝌蚪分别为i,j,k,使用for循环找出
for i in range(len(nums)):
for j in range(i + 1, len(nums)): # j从i+1开始,避免重复选到同一个娃
for k in range(j + 1, len(nums)): # k从j+1开始,避免重复选到同一个娃
if nums[i] + nums[j] + nums[k] == 0:
li = [nums[i], nums[j], nums[k]] # 一组娃
lst.append(li)---------------------------------------------------------------进运行到这
输出:
[[-1, 1, 0], [-1, 1, 0],------>重复
[-1, 0, 1], [-1, -2, 3],
[-1, 0, 1], [1, -2, 1]
[0, -2, 2], [-2, 0, 2]] ------->重复
运行情况
根据暴力解题法,什么叫做暴力?,就是简单粗暴,万事for循环就是暴力解题的精髓.
我们就可以使用for循环一个一个找出第一第二个子列表看它们是否相同,相同则移除一个
# 去重
for x in range(len(lst)):
for y in range(x + 1, len(lst)):
if y < len(lst) and lst[x] == lst[y]: # 因为去重时列表长度改变所以加上限制条件
lst.remove(lst[y]) # y < len(lst)
else:
continue
还有一个问题就是我们可以看到第二处重复, [0, -2, 2], [-2, 0, 2],重复但两个列表并不相等利用上面的去重操作无法去除此类重复,怎么办呢?
观察这两个列表,所含元素一样,但顺序不一样,对于顺序我们便可以利用sort()函先将列表排序然后再去重就好了
完整代码如下
def findChild(nums):lst = [] # 包含结果的列表if len(nums) < 3: # 小于三的列表直接返回[]return(lst)else:for i in range(len(nums)):for j in range(i + 1, len(nums)): # j从i+1开始,避免重复选到同一个娃for k in range(j + 1, len(nums)): # k从j+1开始,避免重复选到同一个娃if nums[i] + nums[j] + nums[k] == 0:li = [nums[i], nums[j], nums[k]] # 一组娃li.sort() # 从小到大排列li,方便后面的去重复lst.append(li) lst.sort() # 排列结果列表,方便后面的去重复for x in range(len(lst)): # 去重for y in range(x + 1, len(lst)):if y < len(lst) and lst[x] == lst[y]:lst.remove(lst[y])else:continuereturn lst
暴力解题,简单明了,一分析花费时间约为O(n^3),n为列表长度.下面我们用另一种方法优化解题速度.
排序+循环+指针
别看见指针就慌其实很容易理解的.
寻找三个数,和为零,不重复.第一第二不都容易操作,那么第三步不循环的本质时什么呢?
怎样获取到一个不重复的子列表[a, b, c],而不是[a,c,b]或[b,c,a]呢?类似暴力解法的分析,三个列表仅元素顺序不同,如何固定元素顺序,使用排序
1.先将nums排序,使其中的元素从小到达排序
这样我们有nums=[a<b<=b<c<d<=d<=d<e........]
接着我们可以使用for循环先找出第一个娃a,接下来两娃的寻找就可以会到双指针问题.
在尾部放一个指针 k ,那首指针 j 放哪才好,放到娃a的后一位,
因为娃使用for循环时是从列表首位置开始
将首指针 j 放到娃a的后一位,这样指针 j 就可以跟着娃a的寻找移动
这时我们得到a+b+c=0,当a,b固定时我们看k指针,因为nums已从小到达排序,ab向右移动时a,b均增大a1 > a, b1 > b,因为a1+b1+c1=0,所以有c1 < c,k指针往左移,则k-1
当指针 j , k ,重合后遍历完可推出循环
def findChild(nums):nums.sort()result_list = list()for i in range(len(nums)): # 选娃aif i > 0 and nums[i] == nums[i - 1]: # 需要和上一次的娃不相同continue # 如果相同选下一个k = len(nums) - 1 # k指针初始指向数组末尾# 选娃b for j in range(i + 1, len(nums)):if j > i + 1 and nums[j] == nums[j - 1]:continuewhile j < k and nums[j] + nums[k] > -nums[i]:# 需要限制 b 的指针在 c 的指针的左侧k -= 1 # 等同于nums[j] + nums[k] + nums[i] > 0if j == k: # 如果指针重合退出循环breakif nums[j] + nums[k] == -nums[i]: # 等同于nums[j] + nums[k] + nums[i] == 0result_list.append([nums[i], nums[j], nums[k]])return result_list
花费的时间约为O(n^2),n为列表长度,主要为两个for循环的开销.比暴力解题快了不少.
有一次寻娃结束
---------------------------------------------------------end------------------------------------------------------------------
Python每日一练-----妈妈找小蝌蚪(进阶版),指针的灵活运用相关推荐
- Python每日一练-----妈妈找小蝌蚪(哈希算法)
题目: 给定一个池塘里面有众多小蝌蚪(整数数组 nums) 他们已经排队好了,有一位青蛙妈妈(一个整数目标值 mom),请你帮助青蛙妈妈找到他的亲生孩子所在的位置(数组序号)(青蛙:生的时候我也没想过 ...
- python 编程一日一练-python每日一练
广告关闭 2017年12月,云+社区对外发布,从最开始的技术博客到现在拥有多个社区产品.未来,我们一起乘风破浪,创造无限可能. 过滤掉列表中的负数 筛选出字典{lilei: 79,jim: 88,lu ...
- Python每日一练0018
问题 你需要对浮点数执行精确的计算操作,并且不希望有任何小误差的出现. Python的float类型是存在误差的 >>> a = 1.1 >>> b = 2.2 & ...
- Python每日一练0023
问题 如何判断一个文件是否存在 解决方案 这个问题可以分成几类问题 如果这里的文件指的是文件或目录,我们可以用os.path.exists()方法 >>> import os > ...
- Python每日一练0004
问题 如何保存迭代对象的最后N个元素 例如保存列表['a', 'b', 'c', 'd']的最后2个元素 或者保存某个迭代器对象的最后5个元素 解决方案 对于列表.元组这样的数据结构,可以使用切片来很 ...
- python 编程一日一练-Python每日一练0022
问题 你想在一个文件里每次读入固定大小的字节,比如每次读入4个字节并转成int,或者每次读入x个字节并进行结构化,例如: l = [5, 2, 4, 1, 2, 4, 5, 6, 8] with op ...
- python 编程一日一练-Python每日一练0013
问题 现在有多个字典或者映射,你想将它们从逻辑上合并为一个单一的映射后执行某些操作, 比如查找值或者检查某些键是否存在. 解决方案 使用collections库的ChainMap类,可以快速的将多个d ...
- python每日一练名片管理程序_Python每日一练0022
问题 你想在一个文件里每次读入固定大小的字节,比如每次读入4个字节并转成int,或者每次读入x个字节并进行结构化,例如: l = [5, 2, 4, 1, 2, 4, 5, 6, 8] with op ...
- [附源码]计算机毕业设计Python+uniapp驾校练车预约小程序9u0r2(程序+lw+远程部署)
[附源码]计算机毕业设计Python+uniapp驾校练车预约小程序9u0r2(程序+lw+远程部署) 该项目含有源码.文档.程序.数据库.配套开发软件.软件安装教程 项目运行环境配置: Python ...
最新文章
- python代码编辑器排行榜-4款好用的Python编辑器,你用过几个?
- 用json 数据生成mysql 表_根据json数据生成表格
- [转]JavaScript:只能输入数字(IE、FF)
- python应用体系_python-大型django应用程序体系结构
- 使用Transformers离线模型(以bert模型为例)
- C# 调用C++DLL注意事项
- hduoj 1518square
- 华为绩效管理PBC:以责任结果为导向,正确评价价值
- Handler看这一篇就够了
- c51单片机流水灯程序汇编语言,基于51单片机的流水灯程序
- 苹果开发者账号授权给普通个人苹果账号上架APP
- Linux C实现纯用户态抢占式多线程!
- LogBack 日志压缩产生上百G的tmp文件问题
- uniapp 微信小程序修改BarTitle
- 机器翻译评估标准介绍和计算方法
- python如何安装keras和tensorflow
- Jenkins 用户角色及权限管理
- ps -aux | grep xxx, kill -s 9, pgrep --Linux下进程
- 【项目回顾】基于Yanshee的AI服务型机器人(三)
- 公司对不实舆情该如何进行处置和公关?
热门文章
- C语言在工业工程专业的应用,工业工程专业.PDF
- 随机性检测模块支持GM/T 0005-2021标准的升级建议
- 《亿级流量网站架构核心技术》.pdf
- 最强软件哪里寻?让你见识什么是第一
- 超声波清洗机电路板线路板设计
- 私、仆、俺 あなた、お前、君 的区别
- 【论文】解读Robust bike-sharing stations allocation and path network design: a two-stage stochastic...
- Linux 结束进程快捷键
- 微信公众平台对接C#-上传永久媒体文件
- android.app.fragment instantiationexception,recreate导致的Fragment报的错误