程序员老鬼

苦逼的程序员,为了结婚,高位接盘买房,房子还没交付,背负了150万的房贷,工作被裁了,刚结婚的老婆,不到两个月跑了

刚看到个贴子,说一个程序员为结婚高位接盘买房,贷款150万,结果房子没交付人被裁,老婆也走了。现在又失眠又失业,还要还26年房贷。网友都在说:“这是真人版社会毒打”。

Image

确实心酸,但也太典型了——年轻人一脚踩进“房子=安全感”的陷阱,结果被现实反噬。买房结婚,本是稳当人生的象征,可放在今天的环境里,成了压垮人的稻草。尤其程序员这行,本身周期短、压力大,一旦被裁,连喘口气的空间都没有。

但话说回来,生活再难,还是得想着“活下去”。卖房赎身也好,从头再来也罢,总比被债和焦虑拖垮强。房子没了能再买,人没了什么都没了。

稳住心态,别被过去绑架。只要人还在,日子就有翻盘的可能。【备注:文末可领最新资料】

算法题:美数对

昨晚十一点多,我在公司楼下啃便利店关东煮,手机叮一下,小李问“东哥,美数对怎么写啊?我脑袋嗡嗡的”。我嘴里还烫着,随口就说:这个题别想复杂,先把题义吃透,十分钟能抡完…咳,结果我回去一跑样例,还是踩了俩小坑,给你们讲讲。

常见版本是这样的:给你一个整型数组 nums,下标 i < j,定义一对 (i, j) 是“美数对”,当且仅当 gcd( firstDigit(nums[i]), lastDigit(nums[j]) ) == 1。就是左边取首位,右边取末位,看它俩是不是互质。注意是互质等于1,不是大于1。嗯,就这么点事。

最直接办法就是双重循环。关键有三个小函数: 1)拿首位数 firstDigit(x),不停除以10直到小于10; 2)拿末位数 x % 10,负数要取绝对值; 3)最大公约数 gcd(a,b),辗转相除就行。 复杂度 O(n²),数组一千来个完全能飞。要再抠性能,可以把“首位∈[1..9]、末位∈[0..9]”的互质关系预计算成 10×10 的布尔表,内层就不调 gcd 了,省点常数时间。

我昨天被两个点绊了一下: (1)如果有 0 结尾的数,gcd(x, 0) = x,所以只有 firstDigit == 1 才能过。 (2)如果可能出现负数(有些题不出现,但谁知道面试官怎么给数据),先取绝对值再处理首末位。

publicclassBeautifulPairs{

publicintnumberOfBeautifulPairs(int[] nums){
// 可选:预计算互质表,减少 gcd 次数
boolean[][] coprime = buildCoprimeTable();
int n = nums.length;
int ans = 0;
for (int i = 0; i < n; i++) {
int fd = firstDigit(nums[i]);
for (int j = i + 1; j < n; j++) {
int ld = Math.abs(nums[j]) % 10;
// 用表查
if (coprime[fd][ld]) ans++;
// 如果不想预表,也可以:
// if (gcd(fd, ld) == 1) ans++;
            }
        }
return ans;
    }

// 取首位:一直 /10 到只剩一位
privateintfirstDigit(int x){
        x = Math.abs(x);
while (x >= 10) x /= 10;
return x;
    }

// 经典辗转相除
@SuppressWarnings("unused")
privateintgcd(int a, int b){
if (a == 0) return Math.abs(b);
if (b == 0) return Math.abs(a);
        a = Math.abs(a); b = Math.abs(b);
while (b != 0) {
int t = a % b;
            a = b;
            b = t;
        }
return a;
    }

// 预计算 0..9 vs 0..9 的互质关系(首位只会用到1..9)
privateboolean[][] buildCoprimeTable() {
boolean[][] ok = newboolean[10][10];
for (int a = 0; a <= 9; a++) {
for (int b = 0; b <= 9; b++) {
                ok[a][b] = gcdFast(a, b) == 1;
            }
        }
return ok;
    }

// 小范围更快的 gcd(位运算版可选,这里用简单写法)
privateintgcdFast(int a, int b){
if (a == 0) return Math.abs(b);
if (b == 0) return Math.abs(a);
        a = Math.abs(a); b = Math.abs(b);
while (b != 0) {
int t = a % b;
            a = b;
            b = t;
        }
return a;
    }

// 小测一下
publicstaticvoidmain(String[] args){
        BeautifulPairs s = new BeautifulPairs();
        System.out.println(s.numberOfBeautifulPairs(newint[]{2,5,1,4})); // 预期:5
        System.out.println(s.numberOfBeautifulPairs(newint[]{11,21,30})); // 解释:fd=1/2/3 与 ld=1/1/0
        System.out.println(s.numberOfBeautifulPairs(newint[]{10,20,31})); // 注意 0 结尾的情况
    }
}

双层循环是 O(n²),单次判断 O(1)。空间 O(1) 或 O(100)(有预表也就常数)。数据量上千都没压力,线上也稳。

-END-

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

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