程序员老鬼

一个不足20人的公司给你开出2万月薪,你敢入职吗?

刚看到个贴子,说一家不到20人的小公司给你开2万月薪,问你敢不敢去。我觉得这事吧,其实核心就一句:钱多事少离家近,你得看看是哪一项在偷偷加难度。

Image

在我看来,关键还是看钱背后要你干啥。小公司开高薪,要么是真缺人才,要么是工作量大得离谱,要么就是在找“全能工具人”。

就像买菜一样,一把青菜卖40块,要么是有机的,要么是有坑的。

换个角度想,小公司也不是不能去,前提是把活儿问清楚,把风险算清楚,把试用期当成互相考察期。别光看2万数字眼睛亮了,结果进去发现得一个人干五个岗位,那真是赚到的是压力。

工资越高越要仔细看合同。靠谱的钱才是真钱。【备注:文末可领最新资料】

面试题:整数替换

下面这题就是那个挺经典的“Integer Replacement(整数替换)”,用 Java 写一写其实不难,主要是想明白“奇数怎么选 +1 还是 -1”这件事。

给你一个正整数 n,你可以做下面三种操作里的一个(一步):

  • 如果 n 是偶数:变成 n / 2
  • 如果 n 是奇数:可以变成 n + 1 或 n - 1

问:最少多少步能把 n 变成 1?

举个简单的例子:

  • n = 88 → 4 → 2 → 1,一共 3 步
  • n = 7 就有很多种走法,比如: 7 → 8 → 4 → 2 → 1(4 步) 7 → 6 → 3 → 2 → 1(4 步)

看着就有点味道了:奇数的时候到底加还是减,才是关键。

最直接但很慢的想法

暴力的思路很简单:

  • n 是偶数:只能走 n / 2

  • n 是奇数:分两路试:

    • 一路做 n - 1
    • 一路做 n + 1
  • 把两条路的结果取最小

可以用递归 + 记忆化(HashMap 存一下中间结果)来剪枝,但本质上还是在两边乱试,虽然能过,但不是最优雅的写法。

关键观察:奇数就看二进制的“尾巴”

偶数很好办,直接除以 2 就行;真正的难点是奇数加 1 还是减 1。

先看二进制,你会发现:

  • 偶数:二进制最后一位一定是 0,除以 2 就是右移一位,尾巴的 0 少一个,很爽。
  • 奇数:最后一位是 1,加一或减一之后,目的都是——尽量把末尾变成一串 0,这样后面才能狂除以 2。

举几个典型奇数:

  1. n = 3:11₂

  • 3 → 2 → 1(2 步)
  • 3 → 4 → 2 → 1(3 步) 所以 3 这个特殊值应该走 -1。
  • n = 7:111₂

    • 7 → 6 (110₂) → 3 (11₂) → 2 → 1
    • 7 → 8 (1000₂) → 4 → 2 → 1 这里加一会让尾巴变成 000,后面一顿除 2,其实整体也很划算。

    经验规则就出来了:

    • 对于奇数 n:

      • 如果 n & 3 == 3(形如 ...11₂),比如 7、15、31 这种,多加 1 会得到更多尾巴 0,选 +1
      • 否则选 -1
      • 如果 n == 3:一定选 -1

      • 否则看看 后两位:

    这个就是很多题解里常见的那句:

    除了 3 以外,奇数时如果末两位是 11 就加一,否则减一。

    配合偶数直接除以 2,我们就可以写一个纯循环、贼快的贪心算法。

    完整 Java 代码

    注意一个坑:n 的范围在 int 内,如果 n = 2147483647,直接 n + 1 会溢出成负数,所以要先转成 long 再操作。

    publicclassSolution{
    publicintintegerReplacement(int n){
    long x = n;          // 防止 n == Integer.MAX_VALUE 时溢出
    int steps = 0;

    while (x != 1) {
    if ((x & 1) == 0) {
    // 偶数,直接除以 2,相当于右移一位
                    x >>= 1;
                } else {
    // 奇数的两种情况
    if (x == 3 || (x & 3) == 1) {
    // x == 3 特判,或者末两位是 01,走 -1
                        x--;
                    } else {
    // 末两位是 11,走 +1,制造更多尾部 0
                        x++;
                    }
                }
                steps++;
            }

    return steps;
        }
    }

    这个写法完全不递归,就一个循环一直把 x 往 1 压,时间复杂度大概是 O(log n),因为每次要么右移一位,要么很快变成偶数再右移,数字的二进制位数一直是往下掉的。

    这题看起来像“搜索题”,其实是个二进制+贪心的小技巧:

    • 偶数直接除 2
    • 奇数根据末两位选加一还是减一,只有 3 是特例要减一

    把这个思路记住,类似“不断缩小数字 + 选择最优路径”的题,很多都能用“看二进制尾巴”这种方式来简化思考。

    -END-

    我为大家打造了一份RPA教程,完全免费:songshuhezi.com/rpa.html

    最后给大家分享一份不错的副业资料,点击下方公众号,回复关键字: 副业 领,也可以链接我微信:hls404