【python基础刷题--4.第二个重复出现的数(程序设计基础期中)】

题目


题目链接

描述
给定一个正整数数组(元素的值都大于零),输出数组中第二个重复出现的正整数,如果没有,则输出字符串"NOT EXIST"。

输入
第一行为整数m,表示有m组数据。
其后每组数据分两行:
第一行为正整数n(3 < n < 500),表示数组的长度;
第二行是n个正整数,正整数间用空格分开。
输出
有m行输出,每行输出对于数组中第二个重复出现的正整数,如果没有,则输出字符串"NOT EXIST"。
在这里插入图片描述

Code

-法1(错误示范)

m=int(input())
lis=[]
lis1=[]
for i in range(m):
    n=int(input())
row= list(input().split())
for i in range(n):
    if x not in lis:
        lis.append(x)
        lis1[i]=1          
    if x in lis:
        index=index(x)
        lis1[index]+=1
    count=0
    for x in range(len(lis)):
        if lis1[x]>1:
            count+=1
            while count==2:
                print(lis[x])
                break
    if count==0:
        print("NOT EXIST")

错误分析

首先这是一段不完整的代码,缺少了求索引的代码

代码修正

m=int(input())
for i in range(m):
    dic = dict()
    n=int(input())
    row=list(input().split())
    for x in row:
        if x not in dic:
            dic[x]=1
        else:
            dic[x]+=1
    lis1=list(dic.keys())
    lis2=list(dic.values())
    count=[]
    for j in range(len(lis2)):
        if lis2[j]>=2:
            count.append(j)
    if len(count)>=2:
        print(int(lis1[count[1]]))
    else:
        print("NOT EXIST")

代码解析

  • 修正的代码虽然可以完成所预期的功能,但是在创建完字典之后,没有很好的利用好这个字典,绕了一步。
  • 是先把字典的键和值作为两个列表,通过下标遍历值列表,如果值>=2,把下标放进count列表
  • 然后再根据count的长度判断有没有符合条件的,如果有就通过找第二个值,把它作为索引对应到键列表获取最终的数字。

代码再优化

m=int(input())
for i in range(m):
    dic = dict()
    n=int(input())
    #这里可以不用转换成列表row=list(input().split())
    for x in input().split():#因为split后返回的就已经是列表了
        if x not in dic:
            dic[x]=1
        else:
            dic[x]+=1
    #在成功创建每个数字对应出现次数的字典之后,我们可以对原来的代码进行优化
    count=[]
    #类似于我用value作为评价指标,对key进行记录
    for key,value in dic.items():#使用items可以同时获取字典的键和值
        if value >=2:##如果值大于等于2了,说明重复出现
            count.append(key)#这时候就把它对应的数字添加到列表里
    if len(count)>=2:
        print(str(count[1]))
    else:
        print("NOT EXIST")

代码解析

优化的代码则是利用键是输出目标,值是筛选条件,通过值把满足条件的键放在count新列表里面,直接输出count的第二个元素。其实修正的代码和再优化的代码都开辟了一个新的列表,然后找它的第二个元素,但是优化的代码使用items不仅看起来思路更清晰,而且更简洁

解题思路

  • 首先,我们看输入的格式和输出的对应关系,第一行告诉我们有几组两行的数据;
  • 接着,我们发现一组数据对应一行输入,所以,我们可以用一个大循环,针对每一组数据输出结果,在下一组数据进入循环后重新来过。(这是一个非常重要的前提思路)
  • 其次,我们要开始对这个问题设计解决方案,题目要求找第二个重复的数
    (其实我觉得这里面是有bug的,因为根据程序来说,它是遍历完所有数字,按顺序记录每个新数的出现次数;而歧义就是我们还可以把题意理解为第二个重复出现的数是5,因为虽然5和7都重复出现了,但是7先比5重复出现完,第二个7在5的前面)
    • 抛开歧义以设计者想让我们设计的程序的角度,我们需要创建一个字典–键是所有出现的数(不重复的)+值是对应数出现的次数
  • 最后,在创建完字典后,我们需要利用字典来找到第二个重复出现的数;
    • 第一,看它的值如果>=2,就说明键重复了;
    • 第二,因为要找的是第二个,所以我们只能通过增加1个新的列表空间进行存储所有重复出现的键;
    • 第三,我们判断新列表的长度,符合后输出第二个元素即为我们的答案

奇技淫巧

  1. Q:多组数据同时分行输入,同时分行输出,该怎么设计?
    –>我们可以使用一个大的for循环,处理完一组数据就print;下一组数据,所有的操作从头来过
  2. 怎么利用遍历创建记录元素出现次数的列表呢?
    –>见代码,可以直接记住,因为很经典!!!
dic=dict()
names=[]#一堆数据
for name in names:
    if name not in dic:
        dic[name]=1
    else:
        dic[name]+=1
  1. 怎么同时获取字典的键和值?
    –>
    字典同时获取键和值的代码为:
for key,value in 字典名.items():

回忆一下,列表同时获取下标和索引的代码为:

for index,value in enumerate(列表名)
  • 17
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值