某程序员吐槽:被捞女给赖上了,怎么能让她自己主动滚蛋。。

文摘   2024-12-26 12:02   陕西  
今天看到一个程序员朋友发的吐槽帖,真的是刷新了我对“捞女”这一现象的认知。

事情是这样的:认识了一年多的女生,最近发现她居然有10多万的网贷债务,还跟他说这些债务是“彩礼的一部分”。

这位程序员小哥直接给了她一刀,表示“不会娶一个快30岁负债累累的女生,自己去找父母还债吧。” 本以为她会立刻离开,结果她居然赖在他的房子里不走,天天等着他下班,给他添堵。

我能理解他的心情。谁受得了?你拼命加班工作,挣来的钱本该用来改善自己的生活,结果却被一个不靠谱的女人给“浪费”了。

你问我怎么让这种人主动滚蛋?首先,勇敢地设立界限!如果她真有“彩礼”这种奇葩的借口,那她自己去找家里人解决,不是你的责任。

其次,不要觉得自己对她有责任,拒绝不等于不关心,但不能让自己在这种关系中耗尽了时间和精力。

最重要的是,要清楚地认识到,自己的时间和金钱都是有限的,不能随便拿来“修复”别人给你带来的麻烦。

要有底线,不然真的是自己给自己找麻烦。搞定自己的生活,远离这些拖累,才是聪明人的做法。

算法题:有效三角形的个数

嗨,大家好。今天咱们聊聊一道挺经典的算法题——“有效三角形的个数”。说实话,这道题给我第一眼看的时候,我脑袋里立刻浮现出的是数学课上三角形的定义:三条边满足三角形不等式定理。也就是说,任意两条边之和必须大于第三条边。那么,这道题的本质就是要判断给定的边长能否组成一个有效的三角形,而这个判断条件就成了我们解决问题的关键。

题目大概是这样的:给定一个长度为n的整数数组,表示三条边的长度,你需要计算可以从数组中选取三条边,且它们能组成一个有效三角形的三元组个数。

听起来是不是很简单?选三条边,检查一下它们是否满足三角形不等式。其实,这个问题表面简单,实际考验的正是如何高效地计算出这些三元组,避免暴力解法的时间复杂度过高。

看看暴力解法

首先,我们来想象一下暴力解法。暴力解法的思路就是三重循环,遍历所有的三条边组合,检查它们是否满足三角形不等式定理:

public class TriangleCount {
    public int countTriangles(int[] nums) {
        int n = nums.length;
        int count = 0;

        for (int i = 0; i < n - 2; i++) {
            for (int j = i + 1; j < n - 1; j++) {
                for (int k = j + 1; k < n; k++) {
                    if (nums[i] + nums[j] > nums[k] &&
                        nums[i] + nums[k] > nums[j] &&
                        nums[j] + nums[k] > nums[i]) {
                        count++;
                    }
                }
            }
        }

        return count;
    }
}

这段代码确实能解决问题,但它的时间复杂度是O(n³),显然对于较大的输入数据,性能会非常低下。对于数组长度达到1000的情况,简直是想让程序员崩溃。所以我们得想办法优化一下。

优化思路:排序 + 双指针

通过排序和双指针方法,我们可以将时间复杂度优化到O(n²),具体是怎么做的呢?我们来详细分析一下。

  1. 首先,排序能帮助我们大大减少不必要的比较。因为当数组排好序之后,任意三条边满足nums[i] + nums[j] > nums[k],就自动满足nums[i] + nums[k] > nums[j]nums[j] + nums[k] > nums[i]。只要nums[i] + nums[j] > nums[k]成立,其他两个条件就自动成立了。

  2. 然后,我们可以固定一个边,使用双指针去判断剩下的两边。比如,我们固定nums[k]作为最大边,然后使用两个指针ij,分别指向nums[k-1]之前的部分,来查找满足条件的组合。

代码实现如下:

import java.util.Arrays;

public class TriangleCount {
    public int countTriangles(int[] nums) {
        Arrays.sort(nums); // 先排序

        int count = 0;
        int n = nums.length;

        for (int k = 2; k < n; k++) {  // 固定最大边 nums[k]
            int i = 0, j = k - 1;  // 双指针,i指向最小边,j指向倒数第二个边
            while (i < j) {
                if (nums[i] + nums[j] > nums[k]) {
                    count += (j - i);  // 说明从i到j之间所有组合都满足条件
                    j--;
                } else {
                    i++;
                }
            }
        }

        return count;
    }
}

解析

  1. 我们先对数组进行排序,这一步的时间复杂度是O(n log n)。
  2. 然后,我们通过一个循环固定最大的边nums[k],接下来,使用两个指针ij分别从0k-1开始,来寻找满足三角形不等式的组合。这个过程的时间复杂度是O(n²)。
  3. nums[i] + nums[j] > nums[k]时,意味着从ij之间所有的组合都符合要求,因此我们可以直接加上(j - i)个三元组。然后,移动指针j,继续寻找其他可能的组合。如果不满足条件,则移动指针i,尝试增加nums[i]的值。

最终,整体时间复杂度就是O(n²),比暴力解法高效得多。

小结

通过这种排序 + 双指针的方法,我们将问题的时间复杂度从O(n³)优化到了O(n²),大大提高了程序的性能。对于大规模的数据,性能的提升是非常明显的。

而且,这道题也让我想到了一个很有趣的点,解决算法问题时,很多时候你不只是想着如何暴力解题,而是通过观察数据的结构,找到一种更加巧妙的方式来减少计算量,就像这道题中通过排序和双指针的方式,我们实际上是利用了数据的顺序性来降低了时间复杂度。

-END-


ok,今天先说到这,老规矩,给大家分享一份不错的副业资料,感兴趣的同学找我领取。

以上,就是今天的分享了,看完文章记得右下角给何老师点赞,也欢迎在评论区写下你的留言

程序员老鬼
10年+老程序员,专注于AI知识普及,已打造多门AI课程,本号主要分享国内AI工具、AI绘画提示词、Chat教程、AI换脸、Chat中文指令、Sora教程等,帮助读者解决AI工具使用疑难问题。
 最新文章