ACM D题 水晶,栈数据结构的运用

先附上原题:

​​​

解法一(通解):

入题思路:       

       在这个题目中,要求我们对所输入的列表中的目标元素进行删除操作,这种涉及搜索和删除等系列的问题,即很类似于常见的深度优先搜索(dfs),这时也就要想到作为深度优先搜索的基础数据结构——栈。

解题步骤:

        如何将栈这个数据结构运用到这道题目呢。

        (1)、在题目中,要求将所给列表中的目标元素删除,可以先初始化一个列表作为栈 stack,用于暂时存储列表的元素,并初始化 cnt ,作为计数器,记录移除的元素,即水晶的个数。

        (2)、当栈为空时,将所输入列表中的元素依次入栈

        (3)、当栈不为空时,在元素入栈时对栈顶元素和等待入栈的元素进行检测。当等待入栈的元素 i 和栈顶的元素 stack[-1] 相同时,将该等待入栈的元素压入栈中。当等待入栈的元素 i 和栈顶的元素 stack[-1] 不相等时(即在所输入的列表中 '0' ,  '1' 两个元素相邻时),不将等待入栈的元素 i 入栈,弹出栈顶元素 stack[-1],并将计数器 cnt 自增2。 

代码实现:

s = input()                   #输入列表
stack = []                    #初始化栈
cnt = 0                       #初始化计数器

for i in s:                   #遍历列表中的元素
    if not stack:             #当栈为空时,将列表元素入栈
        stack.append(i)
    elif stack[-1] == i:      #当栈顶元素和等待入栈的元素相同时
        stack.append(i)       #将等待入栈的元素入栈
    else:
        stack.pop()           #当栈顶元素和等待入栈的元素不同时
        cnt += 2              #将栈顶元素出栈,等待入栈的元素不再入栈,并使计数器自增2

print(cnt)                    #输出结果,即为删除元素的个数

时间复杂度: 

       由代码中不难看出来,再对列表中的元素进行出栈入栈的操作时,要对列表进行一次遍历,遍历循环的次数取决于列表的长度 n ,故可得这种算法的时间复杂度为O(n) 

解法2(优解):

入题思路:

       通过所给的用例进行推到不难得出,在最后完成水晶的删除任务时,列表中的元素仅会出现一种状态,即列表中的元素全为 '0' 或全为 '1' 。这就意味这我们在删除相邻不同元素的水晶时,实际上就是将列表中元素 '0' 和元素 '1'二者中个数的较少的元素删除,即删除 '0' 或 '1' ,取决于这两个元素在列表中的个数。

解题步骤:

        (1)、计算列表中 '0','1' 两种元素的数量

        (2)、比较两种元素数量的大小,取其较小者

        (3)、将较小者的数量乘2,即为所求

代码实现:

s = input()                                   #输入列表
print(min(s.count("0"), s.count("1")) * 2)    #取两中元素来列表中个数的较小者,并乘2

 时间复杂度:

        在 .count 函数中,计算列表中元素的个数需要对列表进行遍历,个解法2的时间复杂度为 O(n) 。而由于 .count 为python的内置函数,故解法2的运行速度会比解法1的的运行速度快。

总结归纳:

       当涉及对列表进行搜索和删除等操作时,我们就要灵活的运用栈这种数据结构,利用其元素先进后出的特性来简化列表中对某一特定元素的进行相关操作。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值