不能直接用 std::min_element 找最短距离,因为它找值最小元素而非值相等元素的最小下标差;题目要求在值相等前提下找下标差绝对值最小的两个元素,暴力法需双重循环并剪枝优化。

为什么不能直接用 std::min_element 找最短距离?
因为 std::min_element 找的是值最小的元素,不是位置最近的两个元素。题目要的是“数组中任意两个元素下标差的绝对值最小”,但前提是这两个元素的**值相等**(否则“距离”无意义——你总不能说 1 和 100 距离近吧?)。实际业务中,这个需求通常出现在:去重前找重复项位置、检测相邻相同状态、压缩序列时识别紧邻重复等场景。
常见错误是误读题意,写成找值最接近的两个数(那是另一类问题,需排序后双指针),或者忽略“相等”前提,直接算所有两两下标差——时间复杂度飙到 O(n²),大数组直接卡死。
暴力法适用小数组,但要注意边界和提前退出
如果数组长度 n ≤ 1000,双重循环仍可接受。关键不是写出来,而是写对:
- 外层索引
i从0到n-2,内层j从i+1开始,避免自比和重复计算 - 只在
arr[i] == arr[j]时更新最小距离min_dist = std::min(min_dist, j - i)(因为j > i,不用abs) - 一旦
min_dist == 1,可立即break——不可能比相邻更近了
示例片段:
int min_dist = INT_MAX; for (int i = 0; i <h3>哈希表一次遍历解决,适合大数组</h3><p>核心思路:对每个值记录它**上一次出现的位置**。遇到重复值时,用当前索引减去上次索引,就是这对元素的距离。时间复杂度 <code>O(n)</code>,空间 <code>O(n)</code>。</p><p>注意点:</p><div class="aritcle_card flexRow artxards"> <div class="artcardd flexRow"> <a class="aritcle_card_img" rel="nofollow" href="/xiazai/gongju/2823" title="C++14"><img src="https://img.php.cn/upload/manual/001/431/639/6ac8b33c327c4749.png" alt="C++14" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a> <div class="aritcle_card_info flexColumn"> <a rel="nofollow" href="/xiazai/gongju/2823" title="C++14" class="overflowclass">C++14</a> <p class="overflowclass">C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。</p> </div> <a rel="nofollow" href="/xiazai/gongju/2823" title="C++14" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a> </div> </div>
- 用
std::unordered_map<t int></t>存值 → 上次下标,初始化为空 - 遍历时,若该值已在 map 中,计算
current_index - last_index并更新最小距离 - 每次都要更新 map 中该值对应的下标为当前索引(保证下次算的是最新一次的距离)
- 整型数组若含负数或大数,
unordered_map没问题;但若元素类型是自定义类,需提供hash和==
示例关键逻辑:
std::unordered_map<int int> last_seen; int min_dist = INT_MAX; for (int i = 0; i <h3>当数组已排序时,别浪费性质——用单次扫描</h3> <p>如果输入保证升序(或降序),重复元素必然连续出现。此时不需要哈希表,也不用二重循环:一遍扫描,只比较 <code>arr[i]</code> 和 <code>arr[i-1]</code> 即可。</p> <p>要点:</p> <ul> <li>从 <code>i = 1</code> 开始,检查 <code>arr[i] == arr[i-1]</code> </li> <li>成立则距离为 <code>1</code>,直接可设 <code>min_dist = 1</code> 并继续(因为可能有更短?不,1 就是最短)</li> <li>但注意:如果只要求返回最小距离值,扫到第一个重复就能返回 1;如果要求返回具体哪两个下标,则需记下 <code>i-1</code> 和 <code>i</code> </li> <li>若数组未排序却强行用此法,结果完全错误——这点极易被忽略</li> </ul> <p>排序前提下的最简实现:</p> <pre class="brush:php;toolbar:false;">int min_dist = INT_MAX; for (int i = 1; i <p>真正容易被忽略的是“相等”这个隐含前提——很多人在调试时发现结果不对,最后才发现自己一直在算不同值之间的下标差。另外,<code>INT_MAX</code> 初始化后没找到重复时需要单独处理,否则返回一个极大值会掩盖逻辑错误。</p>
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










