程序员老鬼

特别讨厌自己的上司,几乎快抑郁了,但是月收入有4万多,到底该不该辞职?

刚看到个贴子,说有人月入四万多,但因为特别讨厌上司,整个人快抑郁了,纠结要不要辞职。

Image

我觉得这事吧,关键还是要想清楚:工作本身给你的是“钱”,还是“价值”。网友里有人劝“忍忍吧,钱多还能治愈一部分痛苦”,也有人说“健康最重要,钱再多也没用”。我倒觉得两边都对,但要看个人主线任务是什么。如果当下主线是搞钱,那就得承认委屈是工资的一部分;可要是已经影响身心健康了,那就是在透支未来,等于喝毒药续命。

换个角度想,辞不辞职其实不是二选一,还可以边干边谋划。比如给自己设个期限:再撑半年,把钱存下来,同时积极找更合适的机会。这样既不放弃高收入,也避免被负面情绪拖垮。【备注:文末可领最新资料】

算法题:一张长椅上的最多学生

昨天晚上十一点多,我在小区门口等外卖,风有点大,手插兜里刷群,有人问那个“长椅能坐最多学生”的题,我脑子里就过电影一样过了一遍。就是那种一排座位,用字符串表示,0是空位、1是已经坐了人,然后还有个k,意思是任意两个人之间至少要隔开k个空位。目标嘛,很简单也很现实:还能塞下几个人,别挤到互相打架那种,嗯对。

想象长椅是一条线,像地铁站那种长椅一格一格的。字符串比如“10001”,k如果是1,那就要求两个人之间至少留一个0。已经坐着的人不能动,我们只往0里补1,尽量多补。这个场景特别像我家楼下那条石凳子,两个老哥先坐下,中间留了四格空,我就得算还能插几个人,不然坐下去要被白眼。对吧。

思路就一个字:贪

别慌张,线性的,别上什么花里胡哨。核心就看“连续的0有多长”。分三种情况哈,我在楼下抽烟的时候就这么掰着手指算的:

  • 开头一段连续0(左边没有人顶着):长度叫L,能放的数量是 L / (k+1) 向下取整。
  • 两个已坐的人之间那段0:长度叫M,因为两边各要空出k个给他们留安全距离,所以中间真正可用是 M - 2k,能放 max(0, (M - 2k) / (k+1))。
  • 结尾一段连续0(右边没顶):同开头,R / (k+1)。

有个小坑,整排如果一个人都没坐,那就从头每隔k+1坐一个,数量是 (n + k) / (k+1)。这个公式我反复在心里算了几遍,嗯,没毛病。等等我接个电话……好了继续说。

Java写法我就直接贴

我写得啰嗦点,多留了注释,别嫌烦。跑起来是O(n),一次扫描,空间O(m)存一下已坐的位置,m是已坐人数,基本忽略。

publicclassBenchMaxStudents{
// s: 座位,'0'空位 '1'有人;k: 两人之间至少隔k个空位
publicstaticintmaxAdditional(String s, int k){
int n = s.length();
// 收集已坐的位置
        java.util.List<Integer> ones = new java.util.ArrayList<>();
for (int i = 0; i < n; i++) {
if (s.charAt(i) == '1') ones.add(i);
        }

// 如果没人坐,直接每隔k+1放一个
if (ones.isEmpty()) {
return (n + k) / (k + 1);
        }

int add = 0;

// 左边开头的一段0:索引[0, firstOne-1],长度就是firstOne
int first = ones.get(0);
        add += first / (k + 1);

// 中间的缝隙:相邻1之间的0段长度 gap = ones[i] - ones[i-1] - 1
for (int i = 1; i < ones.size(); i++) {
int gap = ones.get(i) - ones.get(i - 1) - 1;
int usable = gap - 2 * k; // 两端各让出k
if (usable > 0) {
                add += usable / (k + 1);
            }
        }

// 右边结尾的一段0:索引[lastOne+1, n-1],长度 n-1 - lastOne
int last = ones.get(ones.size() - 1);
int tail = (n - 1) - last;
        add += tail / (k + 1);

return add;
    }

// 小玩具测一下
publicstaticvoidmain(String[] args){
        System.out.println(maxAdditional("10001", 1)); // 中间有3个0,只能再坐1个 -> 1
        System.out.println(maxAdditional("00000", 1)); // 每隔2坐一个 -> 3
        System.out.println(maxAdditional("010010", 2)); // 算算看 -> 0
        System.out.println(maxAdditional("0001000", 1)); // 左右都能塞 -> 2
    }
}

你注意那个中间段的公式,很多人一不小心就写成 (gap - k) / (k + 1),结果在gap等于k+1这种边界会多算一个,我上次深夜改同事代码就是被这个坑了,唉。还有一个小细节,字符串很长的时候别反复切子串,直接按字符扫,省GC,省心。我现在困得不行,回头把这个放到笔记里,哦对了外卖到了我先去拿——

-END-

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

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