算法practice1进阶

7次阅读
没有评论

 

这两个方案是面试中常见的进阶考向,尤其是当面试官追加限制条件(如“不准修改原数组”)时,方案 B 是区分普通候选人和优秀候选人的关键。


方案 A:使用 HashSet (空间换时间)

这是最直观的解法。利用 HashSet 查找元素时间复杂度为 $O(1)$ 的特性,遍历数组并记录已出现的数字。

执行逻辑:

  1. 初始化一个空的 HashSet

  2. 遍历数组中的每一个数字 num

    • 如果 num 已经在 Set 中,说明它是重复的,直接返回。

    • 如果不在,将 num 加入 Set

  3. 遍历结束仍未发现重复,返回 -1。

复杂度分析:

  • 时间复杂度$O(n)$。只需遍历一次数组。

  • 空间复杂度$O(n)$。最坏情况下(没有重复或重复在最后),需要存储 $n-1$ 个数字。


方案 B:二分法 (时间换空间)

这个方案非常巧妙。通常二分法是基于下标搜索,但这里的二分是基于数值范围搜索。

前提条件:题目中提到数字范围在 $1 \sim n-1$(注意:如果包含 $0$,逻辑稍作调整,但原理一致)。

核心思想:

如果 $1 \sim n-1$ 范围内没有重复数字,那么 $1 \sim m$ 这个范围内的数字应该刚好只有 $m$ 个。如果统计发现这个范围内的实际数字个数超过$m$,那么重复数字一定在 $1 \sim m$ 之间。

执行步骤(以范围 $1 \sim 7$ 为例):

  1. 确定范围:初始范围 low = 1, high = 7,中间值 mid = 4

  2. 统计次数:遍历整个数组,计算数值在 $1 \sim 4$ 范围内的数字个数。

  3. 二分收缩

    • 如果统计个数 > 4,说明重复数字在 $1 \sim 4$ 之间,令 high = 4

    • 如果统计个数 <= 4,说明重复数字在 $5 \sim 7$ 之间,令 low = 5

  4. 循环结束:当 low == high 时,就找到了其中一个重复数字。

示例代码 (Java):

Java

public int getDuplicate(int[] nums) {
    int low = 1;
    int high = nums.length - 1;
    while (low <= high) {
        int mid = low + (high - low) / 2;
        int count = countRange(nums, low, mid);
        if (low == high) {
            if (count > 1) return low;
            else break;
        }
        if (count > (mid - low + 1)) {
            high = mid;
        } else {
            low = mid + 1;
        }
    }
    return -1;
}

private int countRange(int[] nums, int low, int mid) {
    int count = 0;
    for (int num : nums) {
        if (num >= low && num <= mid) count++;
    }
    return count;
}

复杂度分析:

  • 时间复杂度$O(n \log n)$。二分查找需要 $\log n$ 次,每次都需要 $O(n)$ 时间遍历数组统计次数。

  • 空间复杂度$O(1)$。只使用了常数个变量,且没有修改原数组


面试总结与对比

方案 时间复杂度 空间复杂度 是否修改原数组 适用场景
原地置换 $O(n)$ $O(1)$ 追求极致性能,允许修改输入。
HashSet $O(n)$ $O(n)$ 内存充足,追求代码简洁。
二分法 $O(n \log n)$ $O(1)$ 内存极其受限,且禁止修改原数组。

面试官通常会先让你写出 $O(n)$ 的原地置换,然后反问:“如果这是只读数据流,不能改数组,你怎么办?”这时候你掏出二分法,Offer 基本上就稳了。

你对这个二分法的“数值范围搜索”逻辑还有什么疑问吗?或者想看看这道题的**快慢指针(类似环形链表)**解法?

正文完
 0
bdspAdmin
版权声明:本站原创文章,由 bdspAdmin 于2026-03-12发表,共计1423字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)

摆渡资源站

文章搜索
一言一句话
-「
热门文章
某个货币持仓增长了一倍,但是 jing流入没有增加多少,为啥

某个货币持仓增长了一倍,但是 jing流入没有增加多少,为啥

  这通常是因为该货币的市值(价格)上涨抵消了持仓量的增加,或者存在某些“非交易性”的变动。 简单来...
mac brew 有没有 markdown 格式化工具

mac brew 有没有 markdown 格式化工具

  在 macOS 上通过 Homebrew (brew) 安装 Markdown 格式化工具非常方...
2026比特币稳赚指南:顶级加密交易策略全揭秘!

2026比特币稳赚指南:顶级加密交易策略全揭秘!

    关键要点 定投(DCA):仍是比特币长期积累的低风险和纪律性策略。 趋势交易和波段...
使用Java类库ta4j计算基金的布林轨

使用Java类库ta4j计算基金的布林轨

ta4j简介 对于做金融分析的从业者而言,python的ta-lib是不可或缺的技术分析库,具有简单易用、功能...
全真早晚功课简介

全真早晚功课简介

         道教的斋醮仪式很多,主要的日常宗教活动是早晚功课经。凡是道教徒每天都要上殿唪诵,所...
最新评论
333985 333985 每天都在战争,希望2026和平.
最新文章
nginx中location匹配规则与proxy_pass代理转发

nginx中location匹配规则与proxy_pass代理转发

  最近使用nginx在服务器上配置,在做路径匹配时上遇到细节上的东西,在此做记录,安装请转 win...
算法practice1进阶

算法practice1进阶

  这两个方案是面试中常见的进阶考向,尤其是当面试官追加限制条件(如“不准修改原数组”)时,方案 B...
算法practice1

算法practice1

  https://github.com/CyC2018/CS-Notes/blob/master/...
胸部爱抚是件迷人的事,如果能掌握诀窍更好──5个胸部爱抚阶段的相关诀窍

胸部爱抚是件迷人的事,如果能掌握诀窍更好──5个胸部爱抚阶段的相关诀窍

  爱抚胸部绝对是性爱前戏中最常见,同时也最重要的一环。只是,大多数的男生虽然都有迷恋女生胸部的倾向...
8招舌吻技巧

8招舌吻技巧

  舌吻技巧1:先从正常的亲嘴开始 先从普通的亲嘴开始,慢慢酝酿舌吻的情绪。保持嘴唇柔软并微微张开,...