找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

4672

积分

0

好友

607

主题
发表于 昨天 23:58 | 查看: 3| 回复: 0

男的急啥呢,房子还没影儿呢,分手倒先挂嘴边了。
女生工作稳定、有能力在婚前自己买套三房,甚至还打算拿它当婚房,这搁大多数人眼里不都挺靠谱的嘛。结果男朋友不高兴了,非要两个人一起买,说要弄个更大、更好的。听着像规划未来,可仔细品品又有点不对味儿。

你想一起买,那可以谈预算、聊城市、算贷款压力——哪怕说一句“我也想参与这个家”,都挺正常。但一上来就是“你买我就分手”,这味道立马就变了,跟抢方向盘似的。

房子是资产,也是底气。尤其是婚前靠自己买的,不偷不抢不啃老,凭什么先被吓一跳。真要打算结婚,那该是两个人一块儿把日子过稳,而不是先把对方的选择权按死。要我看,先别急着选房还是选人,先瞅瞅这个人到底是在想共同生活,还是怕你太有退路。


算法题:输出比赛匹配对

比赛对阵表这题,最容易写歪的地方不是括号,而是轮次。

输入 n = 8,队伍编号从 18,实力已经排好序。第一名打第八名,第二名打第七名,这个没啥好争的。麻烦在下一轮:上一轮生成的匹配结果,本身又要继续被当成一个“队伍”参与配对。

比如第一轮是这样:

(1,8)
(2,7)
(3,6)
(4,5)

下一轮不是随便拼,而是继续头尾匹配:

((1,8),(4,5))
((2,7),(3,6))

最后得到:

(((1,8),(4,5)),((2,7),(3,6)))

这块儿我一般不先想递归。递归当然能做,但这题的数据推进很直——像一排人站队,每轮把最左和最右拉出来打一场,然后形成新的一排。用数组模拟反而不容易出错。

代码可以这么写:

class Solution {
    public String findContestMatch(int n) {
        String[] round = new String[n];

        for (int i = 0; i < n; i++) {
            round[i] = String.valueOf(i + 1);
        }

        int size = n;
        while (size > 1) {
            String[] next = new String[size / 2];

            int left = 0;
            int right = size - 1;
            int idx = 0;

            while (left < right) {
                next[idx++] = "(" + round[left] + "," + round[right] + ")";
                left++;
                right--;
            }

            round = next;
            size = next.length;
        }

        return round[0];
    }
}

不需要在这儿硬塞一堆数学推导。你盯住 round 这个数组就行——它每一轮表示“当前还在比赛里的位置”。

第一次:

round = ["1","2","3","4","5","6","7","8"]

配完以后变成:

round = ["(1,8)","(2,7)","(3,6)","(4,5)"]

再配一次:

round = ["((1,8),(4,5))","((2,7),(3,6))"]

最后剩一个,就是答案。

这里有个小坑:别把 n 当成固定长度一路用到底。每打一轮,队伍数量都会减半,所以循环里得维护一个当前长度 size。如果还用原来的 n 去扫数组,后面要么越界,要么拼出来一堆空值。

这道 LeetCode 题还有另一种写法,用 List<String> 会更顺手,尤其是面试现场写代码时,能少处理数组长度。

import java.util.ArrayList;
import java.util.List;

class Solution {
    public String findContestMatch(int n) {
        List<String> teams = new ArrayList<>();

        for (int id = 1; id <= n; id++) {
            teams.add(String.valueOf(id));
        }

        while (teams.size() > 1) {
            List<String> nextRound = new ArrayList<>();
            int l = 0;
            int r = teams.size() - 1;

            while (l < r) {
                String match = "(" + teams.get(l) + "," + teams.get(r) + ")";
                nextRound.add(match);
                l++;
                r--;
            }

            teams = nextRound;
        }

        return teams.get(0);
    }
}

我更喜欢第二种,代码读起来像真实比赛推进:本轮队伍进来,配完生成下一轮。没有额外状态,也不用猜某个下标到底属于第几轮。

复杂度也挺干净。每一轮都要处理当前所有队伍的一半,整体看下来每个编号都会被拼进字符串里,括号和逗号也会不断增加,所以时间主要花在字符串构造上。按算法题的口径,可以认为模拟轮次是 O(n log n) 级别;空间就是保存每轮结果,O(n)

这题别想复杂。它不是让你算冠军,也不是让你真的模拟胜负,它只是让你按规则把对阵表打印出来。头尾配对,生成下一轮,直到只剩一个字符串,停在这儿就够了。

如果你也有类似的生活困惑或者算法题解,欢迎到云栈社区 一起聊聊。




上一篇:南航00后自制火箭二代成功发射,反推垂直回收系统异常
下一篇:电商高可用存储架构:基于单据号路由的流水数据异地多活实践
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-5-10 01:36 , Processed in 1.016360 second(s), 41 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表