0

0

Dota 2 Senate 解题指南:避免遍历中修改列表的陷阱与高效模拟策略

碧海醫心

碧海醫心

发布时间:2026-01-22 13:02:12

|

661人浏览过

|

来源于php中文网

原创

Dota 2 Senate 解题指南:避免遍历中修改列表的陷阱与高效模拟策略

本文详解 leetcode “dota 2 senate” 问题中常见的逻辑错误——在 for 循环中直接修改正在遍历的列表导致跳过元素,并提供基于分组+循环链表的高效、正确解法。

你在 DRRD 测试用例中得到 "Radiant"(错误)而非预期的 "Dire",根本原因在于在 for senator in senators: 循环中调用 senators.remove(...) 动态修改列表长度。Python 的 for 循环底层通过索引递增遍历,当删除前方元素后,后续元素整体前移,但循环索引仍按原步进递增,从而跳过紧邻被删元素之后的那个元素。

以 ['D','R','R','D'] 为例:

  • 初始索引 i=0 → 取 'D',执行 remove("R") → 列表变为 ['D','R','D'];
  • 下次索引 i=1 → 实际取到的是原索引 2 的 'R'(即第二个 'R'),而原索引 1 的 'R' 已被跳过;
  • 接着 i=2 → 取 'D',再删 "R" → 列表变为 ['R','D'];
  • 此时循环结束(因原列表长度为 4,只迭代了 3 次),最后一个 'D' 在首轮未被处理,导致策略失真。

更深层问题在于:贪心删除“第一个出现的对手”并非最优策略。游戏规则是“按顺序轮流禁言”,应优先禁言下一个将获得发言权的对手(即循环队列中当前 senator 后方最近的对手),而非列表开头的第一个对手。这天然具有循环性,普通线性列表难以高效建模。

✅ 正确解法思路:分组 + 循环链表 + 延迟淘汰

如此AI员工
如此AI员工

国内首个全链路营销获客AI Agent

下载
  • 分组压缩:利用正则 r"R+|D+" 将连续相同阵营合并为一个节点(如 "DRRD" → R(1)→R(2)→D(1)?不对,应为 D(1)→RR(2)→D(1);实际 "DRRD" 分组为 "D","RR","D" → D(1)→R(2)→D(1));
  • 循环链表:首尾相接,支持 O(1) 删除与遍历;
  • 状态管理:记录当前节点中已行使投票权的议员数 i,结合对方节点剩余人数,计算本次能禁言多少人,避免重复遍历。

以下是优化后的完整实现(含详细注释):

import re

class Solution:
    class Node:
        def __init__(self, party: str, count: int):
            self.party = party
            self.count = count
            self.next = None

    def predictPartyVictory(self, senate: str) -> str:
        # Step 1: 构建分组循环链表
        # 例如 "DRRD" → ["D", "RR", "D"] → D(1) → R(2) → D(1) → back to D(1)
        sentinel = tail = Solution.Node("", 0)
        for group in re.findall(r"R+|D+", senate):
            tail.next = Solution.Node(group[0], len(group))
            tail = tail.next
        head = sentinel.next  # 跳过哨兵
        tail.next = head      # 成环

        # Step 2: 模拟投票过程
        # curr: 当前处理节点;i: curr 中已投票的议员数
        curr = head
        i = 0
        while curr.next != curr:  # 至少两个不同阵营节点
            nxt = curr.next
            if nxt.party == curr.party:
                # 同阵营:合并节点
                curr.count += nxt.count
                curr.next = nxt.next
            else:
                # 异阵营:curr 中剩余可投票人数 = curr.count - i
                remaining_votes = curr.count - i
                # 最多禁言 min(己方可投数, 对方可存数)
                banned = min(remaining_votes, nxt.count)
                nxt.count -= banned
                i += banned  # 更新已投票数
                if nxt.count == 0:
                    # 对方节点清空,移除
                    curr.next = nxt.next
                if i == curr.count:
                    # 当前节点全员投票完毕,切换到下一节点
                    i = 0
                    curr = curr.next

        # 唯一剩余节点即胜者
        return "Radiant" if curr.party == "R" else "Dire"

? 关键注意事项

  • ❌ 避免在 for/while 遍历列表时调用 list.remove() 或 del —— 改用索引倒序遍历或构建新列表;
  • ✅ 分组压缩将时间复杂度从 O(n²) 降至接近 O(n),尤其对长连续序列(如 "R"*1000 + "D")效果显著;
  • ⚠️ 循环链表需严格维护 next 指针,删除节点时务必更新前驱的 next,防止内存泄漏或无限循环;
  • ? 该解法本质是模拟“带计数的循环队列”,i 变量巧妙复用了当前节点的“已消耗投票额度”,无需额外队列存储待处理议员。

此方案通过数据结构升级规避了原始逻辑缺陷,既保证正确性,又具备工业级可扩展性。

相关专题

更多
python开发工具
python开发工具

php中文网为大家提供各种python开发工具,好的开发工具,可帮助开发者攻克编程学习中的基础障碍,理解每一行源代码在程序执行时在计算机中的过程。php中文网还为大家带来python相关课程以及相关文章等内容,供大家免费下载使用。

772

2023.06.15

python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

661

2023.07.20

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

764

2023.07.25

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

679

2023.07.31

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

1365

2023.08.03

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

569

2023.08.04

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

579

2023.08.04

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

730

2023.08.11

菜鸟裹裹入口以及教程汇总
菜鸟裹裹入口以及教程汇总

本专题整合了菜鸟裹裹入口地址及教程分享,阅读专题下面的文章了解更多详细内容。

0

2026.01.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 13.6万人学习

Django 教程
Django 教程

共28课时 | 3.4万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号