男朋友说我自己婚前买了房就分手,怎么破?
这男朋友急啥呢,急到房子还没买,分手先挂嘴边了。
女生工作稳定,自己有能力婚前买个三房,还说能当婚房,这放很多人眼里不就是挺靠谱吗?结果男朋友不高兴了,说要两个人一起买,买大的好的。听着像规划未来,细品又有点别扭。
你想一起买,可以谈预算、谈城市、谈贷款压力,哪怕说“我也想参与这个家”,都正常。但一上来就是“你买我就分手”,这味儿就变了,像是在抢方向盘。
房子是资产,也是底气。尤其婚前自己能买,不偷不抢不啃老,凭什么先被吓一跳。真要结婚,应该是两个人一起把日子过稳,不是先把对方的选择权按住。
要我看,先别急着选房还是选人,先看看这个人到底是在想共同生活,还是在怕你太有退路。
算法题:输出比赛匹配对
比赛对阵表这题,最容易写歪的地方不是括号,是轮次。
输入 n = 8,队伍编号从 1 到 8,实力已经排好序。第一名打第八名,第二名打第七名,这个没啥好争的。麻烦在下一轮:上一轮生成的匹配结果,本身又要继续被当成一个“队伍”参与配对。
比如第一轮是这样:
(1,8)
(2,7)
(3,6)
(4,5)
下一轮不是随便拼,而是继续头尾匹配:
((1,8),(4,5))
((2,7),(3,6))
最后得到:
(((1,8),(4,5)),((2,7),(3,6)))
这地方我一般不先想递归。递归当然能做,但这题的数据推进很直,像一排人站队,每轮把最左和最右拉出来打一场,然后形成新的一排。用数组模拟,反而不容易出错。
代码可以这么写:
classSolution{
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 去扫数组,后面不是数组越界,就是拼出来一堆空值。
这题还有一种写法,用 List<String> 会更顺手一点,尤其是面试现场写代码,少处理数组长度。
import java.util.ArrayList;
import java.util.List;
classSolution{
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)。
这题别想复杂。它不是让你算冠军,也不是让你真的模拟胜负。它只是让你按规则把对阵表打印出来。
头尾配对,生成下一轮,直到只剩一个字符串。停在这里就够了。