Skip to content

Commit d61b3a2

Browse files
committed
add BeautifulArray
1 parent f0a7561 commit d61b3a2

File tree

2 files changed

+120
-0
lines changed

2 files changed

+120
-0
lines changed

hi-leetcode/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
| 0904 | [Fruit Into Baskets](https://leetcode.com/problems/fruit-into-baskets/) | [Java](./src/main/java/me/meet/leetcode/medium/FruitIntoBaskets.java) | Medium |
6060
| 0918 | [Maximum Sum Circular Subarray](https://leetcode.com/problems/maximum-sum-circular-subarray/) | [Java](./src/main/java/me/meet/leetcode/medium/MaximumSumCircularSubarray.java) | Medium |
6161
| 0919 | [Complete Binary Tree Inserter](https://leetcode.com/problems/complete-binary-tree-inserter/) | [Java](./src/main/java/me/meet/leetcode/medium/CompleteBinaryTreeInserter.java) | Medium |
62+
| 0932 | [Beautiful Array](https://leetcode.com/problems/beautiful-array/) | [Java](./src/main/java/me/meet/leetcode/medium/BeautifulArray.java) | Medium |
6263
| 0939 | [Minimum Area Rectangle](https://leetcode.com/problems/minimum-area-rectangle/) | [Java](./src/main/java/me/meet/leetcode/medium/MinimumAreaRectangle.java) | Medium |
6364
| # | # | # | # |
6465
| 0937 | [Reorder Data in Log Files](https://leetcode.com/problems/reorder-data-in-log-files/) | [Java](./src/main/java/me/meet/leetcode/easy/ReorderDataInLogFiles.java) | Easy |
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
package me.meet.leetcode.medium;
2+
3+
import java.util.ArrayList;
4+
import java.util.HashMap;
5+
import java.util.List;
6+
import java.util.Map;
7+
8+
public final class BeautifulArray {
9+
private BeautifulArray() {
10+
}
11+
/**
12+
* 932. Beautiful Array
13+
* For some fixed `N`, an array `A` is *beautiful* if it is a permutation of the integers `1, 2, ..., N`, such that:
14+
* For every i < j, there is no k with i < k < j such that A[k] * 2 = A[i] + A[j].
15+
* Given N, return any beautiful array A. (It is guaranteed that one exists.)
16+
*
17+
* Example 1:
18+
* Input: 4
19+
* Output: [2,1,4,3]
20+
*
21+
* Example 2:
22+
* Input: 5
23+
* Output: [3,1,2,5,4]
24+
*
25+
* Note:
26+
* 1 <= N <= 1000
27+
*/
28+
/**
29+
* 漂亮数组
30+
* 对于某些固定的 N,如果数组 A 是整数 1, 2, ..., N 组成的排列,使得:
31+
* 对于每个 i < j,都不存在 k 满足 i < k < j 使得 A[k] * 2 = A[i] + A[j]。
32+
* 那么数组 A 是漂亮数组。
33+
* 给定 N,返回任意漂亮数组 A(保证存在一个)。
34+
*
35+
* 示例 1:
36+
* 输入:4
37+
* 输出:[2,1,4,3]
38+
*
39+
* 示例 2:
40+
* 输入:5
41+
* 输出:[3,1,2,5,4]
42+
*
43+
* 提示:
44+
* 1 <= N <= 1000
45+
*/
46+
/**
47+
* 思路:
48+
* 这道题定义了一种漂亮数组,说的是在任意两个数字之间,不存在一个正好是这两个数之和的一半的数字,现在让返回长度是N的一个漂亮数组,注意这里长度是N的漂亮数组一定是由1到N之间的数字组成的,每个数字都会出现,而且一定存在这样的漂亮数组。博主刚开始时是没什么头绪的,想着总不会是要遍历所有的排列情况,然后对每个情况去验证是否是漂亮数组的吧,想想都觉得很不高效,于是就放弃挣扎,直接逛论坛了。不出意外,最高票的还是你李哥,居然提出了逆天的线性时间的解法,献上膝盖,怪不得有网友直接要 Venmo 号立马打钱,LOL~ 这道题给了提示说是要用分治法来做,但是怎么分是这道题的精髓,若只是普通的对半分,那么在 merge 的时候还是要验证是否是漂亮数组,麻烦!
49+
* 但若按奇偶来分的话,那就非常的叼了,因为奇数加偶数等于奇数,就不会是任何一个数字的2倍了。这就是奇偶分堆的好处,这时任意两个数字肯定不能分别从奇偶堆里取了,那可能你会问,奇数堆会不会有三个奇数打破这个规则呢?
50+
* 只要这个奇数堆是从一个漂亮数组按固定的规则变化而来的,就能保证一定也是漂亮数组,因为对于任意一个漂亮数组,若对每个数字都加上一个相同的数字,或者都乘上一个相同的数字,则一定还是漂亮数组,因为数字的之间的内在关系并没有改变。
51+
* 明白了上面这些,基本就可以解题了,假设此时已经有了一个长度为n的漂亮数组,如何将其扩大呢?可以将其中每个数字都乘以2并加1,就都会变成奇数,并且这个奇数数组还是漂亮的,然后再将每个数字都乘以2,那么都会变成偶数,并且这个偶数数组还是漂亮的,两个数组拼接起来,就会得到一个长度为 2n 的漂亮数组。
52+
* 就是这种思路,可以从1开始,1本身就是一个漂亮数组,然后将其扩大,注意这里要卡一个N,不能让扩大的数组长度超过N,只要在变为奇数和偶数时加个判定就行了,将不大于N的数组加入到新的数组中,
53+
*/
54+
static int[] beautifulArray(int n) {
55+
List<Integer> res = new ArrayList<>();
56+
res.add(1);
57+
for (; res.size() < n; ) {
58+
List<Integer> tmp = new ArrayList<>();
59+
for (Integer i : res) {
60+
int num = i * 2 - 1;
61+
if (num <= n) {
62+
tmp.add(num);
63+
}
64+
}
65+
for (Integer i : res) {
66+
int num = i * 2;
67+
if (num <= n) {
68+
tmp.add(num);
69+
}
70+
}
71+
res = tmp;
72+
}
73+
return res.stream().mapToInt(Integer::valueOf).toArray();
74+
}
75+
76+
static int[] beautifulArray1(int n) {
77+
return f(n);
78+
}
79+
80+
final static Map<Integer, int[]> memo = new HashMap<>();
81+
82+
private static int[] f(int n) {
83+
if (memo.containsKey(n)) {
84+
return memo.get(n);
85+
}
86+
int[] ans = new int[n];
87+
if (1 == n) {
88+
ans[0] = 1;
89+
} else {
90+
int t = 0;
91+
for (int x : f((n + 1) / 2)) { // odds
92+
ans[t++] = 2 * x - 1;
93+
}
94+
for (int x : f(n / 2)) { // evens
95+
ans[t++] = 2 * x;
96+
}
97+
}
98+
memo.put(n, ans);
99+
return ans;
100+
}
101+
102+
private static void testBeautifulArray() {
103+
int n = 5;
104+
int[] ans1 = beautifulArray(n);
105+
for (int i : ans1) {
106+
System.out.print(i);
107+
}
108+
System.out.println();
109+
110+
int[] ans2 = beautifulArray1(n);
111+
for (int i : ans2) {
112+
System.out.print(i);
113+
}
114+
}
115+
116+
public static void main(String[] args) {
117+
testBeautifulArray();
118+
}
119+
}

0 commit comments

Comments
 (0)