程序员老鬼

某大厂员工自曝:40+岁,离职前P8年薪130万,休息快2年,今天收到70万年薪的offer,很犹豫,怕之后的薪资就涨不上去了。

40多岁,上一份还是大厂P8,年包130万,歇了快两年,最近终于来个70万offer,结果人先卡住了:接吧,像打了个对折;不接吧,市场又不是慈善局。

Image

这事最扎心的根本不是70万低,是你见过130万以后,脑子里的价签就撕不掉了。人很难从“我值这个数”,一下切到“先有班上再说”。评论区也挺真实,有人说40+还能拿70万,已经赢一片了;也有人说一旦降档,后面基本就按这个线慢慢磨,很难再弹回去。

但职场这玩意,很多时候真不按自尊走,按现金流走。休息两年,市场早不是你离开那会儿的脾气了。70万听着肉疼,可再空转下去,HR看简历都得先琢磨你这两年到底在干嘛。成年人纠结半天,最后多半还是先上车。

面试题:轮转数组

数组轮转这题,代码短,坑一点不少。面试里最常见的死法不是不会写,是 k 没先取模,或者开了个新数组写得挺顺,结果追问一句“能不能原地改”,人就开始卡了。

题目不复杂:给你一个数组,向右轮转 k 次。 比如 [1,2,3,4,5,6,7],k=3,最后要变成 [5,6,7,1,2,3,4]。

这题我一般先不看花活,先看两个地方: 一个是 k 会不会比数组长度大。 另一个是数组长度是不是 0 或 1。 这俩不先处理,后面代码写再漂亮也容易翻车。

很多人第一反应是开临时数组,这个能过,逻辑也直:

publicclassRotateArrayDemo{
publicvoidrotate(int[] nums, int k){
if (nums == null || nums.length < 2) {
return;
        }

int n = nums.length;
        k = k % n;
if (k == 0) {
return;
        }

int[] copy = newint[n];
for (int i = 0; i < n; i++) {
int newIndex = (i + k) % n;
            copy[newIndex] = nums[i];
        }

for (int i = 0; i < n; i++) {
            nums[i] = copy[i];
        }
    }
}

这写法没毛病,时间复杂度 O(n),但空间也用了 O(n)。题目要是继续追“空间复杂度降到 O(1)”,就得换套路。

原地做法我更喜欢翻转。别一上来背结论,顺一下就明白了。 还是 [1,2,3,4,5,6,7],右移 3 位:

先整体翻转:[7,6,5,4,3,2,1]

再翻转前 3 个:[5,6,7,4,3,2,1]

最后翻转后 4 个:[5,6,7,1,2,3,4]

代码这样写就够了,不用绕:

publicclassRotateArrayDemo{
publicvoidrotate(int[] nums, int k){
if (nums == null || nums.length < 2) {
return;
        }

int n = nums.length;
        k = k % n;
if (k == 0) {
return;
        }

        reverse(nums, 0, n - 1);
        reverse(nums, 0, k - 1);
        reverse(nums, k, n - 1);
    }

privatevoidreverse(int[] nums, int left, int right){
while (left < right) {
int tmp = nums[left];
            nums[left] = nums[right];
            nums[right] = tmp;
            left++;
            right--;
        }
    }
}

这题真正该记住的不是“翻转三次”,而是这几个小判断:

k = k % n 必须先做,不然轮转 100 万次这种输入纯属白干。k == 0 直接返回,别让代码多跑三次翻转。nums.length < 2 也直接走,单元素数组怎么转都一样。

面试官拿这题,不是在看你会不会搬公式,主要看你写代码的时候稳不稳。数组题就这样,看着像送分,细节没收住,一样掉坑里。