题目:

给定一个池塘里面有众多小蝌蚪(整数数组 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每日一练-----妈妈找小蝌蚪(进阶版),指针的灵活运用相关推荐

  1. Python每日一练-----妈妈找小蝌蚪(哈希算法)

    题目: 给定一个池塘里面有众多小蝌蚪(整数数组 nums) 他们已经排队好了,有一位青蛙妈妈(一个整数目标值 mom),请你帮助青蛙妈妈找到他的亲生孩子所在的位置(数组序号)(青蛙:生的时候我也没想过 ...

  2. python 编程一日一练-python每日一练

    广告关闭 2017年12月,云+社区对外发布,从最开始的技术博客到现在拥有多个社区产品.未来,我们一起乘风破浪,创造无限可能. 过滤掉列表中的负数 筛选出字典{lilei: 79,jim: 88,lu ...

  3. Python每日一练0018

    问题 你需要对浮点数执行精确的计算操作,并且不希望有任何小误差的出现. Python的float类型是存在误差的 >>> a = 1.1 >>> b = 2.2 & ...

  4. Python每日一练0023

    问题 如何判断一个文件是否存在 解决方案 这个问题可以分成几类问题 如果这里的文件指的是文件或目录,我们可以用os.path.exists()方法 >>> import os > ...

  5. Python每日一练0004

    问题 如何保存迭代对象的最后N个元素 例如保存列表['a', 'b', 'c', 'd']的最后2个元素 或者保存某个迭代器对象的最后5个元素 解决方案 对于列表.元组这样的数据结构,可以使用切片来很 ...

  6. python 编程一日一练-Python每日一练0022

    问题 你想在一个文件里每次读入固定大小的字节,比如每次读入4个字节并转成int,或者每次读入x个字节并进行结构化,例如: l = [5, 2, 4, 1, 2, 4, 5, 6, 8] with op ...

  7. python 编程一日一练-Python每日一练0013

    问题 现在有多个字典或者映射,你想将它们从逻辑上合并为一个单一的映射后执行某些操作, 比如查找值或者检查某些键是否存在. 解决方案 使用collections库的ChainMap类,可以快速的将多个d ...

  8. python每日一练名片管理程序_Python每日一练0022

    问题 你想在一个文件里每次读入固定大小的字节,比如每次读入4个字节并转成int,或者每次读入x个字节并进行结构化,例如: l = [5, 2, 4, 1, 2, 4, 5, 6, 8] with op ...

  9. [附源码]计算机毕业设计Python+uniapp驾校练车预约小程序9u0r2(程序+lw+远程部署)

    [附源码]计算机毕业设计Python+uniapp驾校练车预约小程序9u0r2(程序+lw+远程部署) 该项目含有源码.文档.程序.数据库.配套开发软件.软件安装教程 项目运行环境配置: Python ...

最新文章

  1. python代码编辑器排行榜-4款好用的Python编辑器,你用过几个?
  2. 用json 数据生成mysql 表_根据json数据生成表格
  3. [转]JavaScript:只能输入数字(IE、FF)
  4. python应用体系_python-大型django应用程序体系结构
  5. 使用Transformers离线模型(以bert模型为例)
  6. C# 调用C++DLL注意事项
  7. hduoj 1518square
  8. 华为绩效管理PBC:以责任结果为导向,正确评价价值
  9. Handler看这一篇就够了
  10. c51单片机流水灯程序汇编语言,基于51单片机的流水灯程序
  11. 苹果开发者账号授权给普通个人苹果账号上架APP
  12. Linux C实现纯用户态抢占式多线程!
  13. LogBack 日志压缩产生上百G的tmp文件问题
  14. uniapp 微信小程序修改BarTitle
  15. 机器翻译评估标准介绍和计算方法
  16. python如何安装keras和tensorflow
  17. Jenkins 用户角色及权限管理
  18. ps -aux | grep xxx, kill -s 9, pgrep --Linux下进程
  19. 【项目回顾】基于Yanshee的AI服务型机器人(三)
  20. 公司对不实舆情该如何进行处置和公关?

热门文章

  1. C语言在工业工程专业的应用,工业工程专业.PDF
  2. 随机性检测模块支持GM/T 0005-2021标准的升级建议
  3. 《亿级流量网站架构核心技术》.pdf
  4. 最强软件哪里寻?让你见识什么是第一
  5. 超声波清洗机电路板线路板设计
  6. 私、仆、俺 あなた、お前、君 的区别
  7. 【论文】解读Robust bike-sharing stations allocation and path network design: a two-stage stochastic...
  8. Linux 结束进程快捷键
  9. 微信公众平台对接C#-上传永久媒体文件
  10. android.app.fragment instantiationexception,recreate导致的Fragment报的错误