Leetcode【526、667、932】

题目描述:【DFS】526. Beautiful Arrangement
解题思路:

这道题是一道构造题,即构造一个长度为 N 的自然序列,满足整除关系: i % nums[i] = 0nums[i] % i = 0(i 为第 i 个位置)。由于看到数据范围 N <= 15,因此很容易想到这道题用深搜(DFS)去做。

刚开始的做法是先通过 DFS 构造出一个个完整的序列,然后再对完整序列判断每个位置是否满足要求,结果 TLE 了。后来又想了一下,其实可以在构造的过程中就判断当前构造的这个序列的每个位置是否满足上述整除关系,如果有一个位置不满足,就不用继续构造下去了(即相当于剪枝操作)。这样省了一大笔时间,题目就 AC 了。

Python3 实现:
class Solution:
    def __init__(self):
        self.b = [False] * 16  # 标记数字 i 是否被使用过
        self.ans = 0  # 结果
    
    def countArrangement(self, N: int) -> int:
        self.search(N, 1)
        return self.ans
        
    def search(self, N, r):
        for i in range(1, N+1):
            if self.b[i] == False and (i % r == 0 or r % i == 0):  # 如果不满足整除关系,就不用继续搜索该组解
                self.b[i] = True
                if N == r:  # 找到一组解
                    self.ans += 1
                else:
                    self.search(N, r+1)
                self.b[i] = False  # 恢复,回溯一步

题目描述:【Math】667. Beautiful Arrangement II
解题思路:

这道题是一道构造题,即构造一个长度为 n 的自然序列,这个序列相邻元素差的绝对值的数量为 k 个。看到数据范围是 10^4,首先排除用 DFS 的方法构造序列,然后判断是否满足题意的这种做法。

但是,乍一看也没有什么思路。因此需要从数学的角度找找规律。首先可以确定一点:对于长度为 n 的序列,元素差最多为 n-1 个,且这 n-1 个差分别为 1~(n-1)。这 n-1 个差的构成也很容易发现,较小的数和较大的数交替形成的序列就满足要求。

举个例子,假设 n = 8,k = 7,那么这个序列就是 1 8 2 7 3 6 4 5,形成的 k 个元素差为:7 6 5 4 3 2 1;若 k 不等于 n-1,假设 k = 4,我们只需要按上述规律形成满足长度为 k+1 的序列,剩余元素按递增顺序安排即可(剩余数的差值都为 1),最终得到的序列是:(1 5 2 4 3) 6 7 8,形成的 k 个元素差为:(4 3 2 1) 3 1 1(后面 3 个数的差值为 1)。

时间复杂度为 O(n)。

Python3 实现:
class Solution:
    def constructArray(self, n: int, k: int) -> List[int]:
        ans = [1]
        cnt = 1
        for i in range(n):
            if k > 0:
                if cnt % 2 == 1:  # 下一个数为较大的数
                    ans.append(ans[-1]+k)
                else:  # 下一个数为较小的数
                    ans.append(ans[-1]-k)
                k -= 1
                cnt += 1
            else:
                break
        for i in range(cnt+1, n+1):  # 如果k<n-1,则安排剩余的数按递增顺序排列
            ans.append(i)
        return ans

题目描述:【Math】932. Beautiful Array
解题思路:

这道题也是一道构造题,即构造一个长度为 N 的自然序列,这个序列满足条件: 对于任意的 i < j < k,有 2 * A[k] != A[i] + A[j]。这个序列叫做美丽数组看到数据范围是 1000,首先也先排除用 DFS 的方法构造序列,然后判断是否满足题意的这种做法。

但是,乍一看也没有什么思路。因此需要从数学的角度找找规律。注意到,美丽数组有如下数学性质:
1、A 是一个漂亮数组,对于 A 中的位置 k,k 左边的都是奇数,k 右边的都是偶数(或者 k 左边的都是偶数,k 右边的都是奇数),因为这样安排就一定能保证 2 * A[k] != A[i] + A[j] (偶数 != 奇数 + 偶数 或 偶数 != 偶数 + 奇数);
2、A 是一个漂亮数组,如果对 A 中所有元素加(或减)一个常数,那么 A 还是一个漂亮数组;
3、A 是一个漂亮数组,如果对 A 中所有元素乘上一个常数,那么 A 还是一个漂亮数组;
4、A 是一个漂亮数组,如果删除A 中的一些元素,那么 A 还是一个漂亮数组,因为是对于任意的 i < k < j 都有 2 * A[k] != A[i] + A[j],删除一些元素并不会改变这种顺序;
5、A 是一个由奇数构成的漂亮数组,B 是一个偶数构成的漂亮数组,那么 A + B 也是一个漂亮数组,如: {1,5,3,7} + {2,6,4,8} = {1,5,3,7,2,6,4,8} 也是一个漂亮数组。

有了上述几条性质,我们就可以解决本题的构造问题了。

我们知道一个漂亮数组 A 可以分为奇数部分 A1 和偶数部分 A2(性质 1)。此时如果有一个漂亮数组 B,那么 2*B-1 是一个漂亮数组(性质 2、3)并且是奇数数组,而 2*B 也是一个漂亮数组(性质 2)并且是偶数数组。那么我们通过[2*B-1] + [2*B] 得到的必然也是一个漂亮数组(性质 5)。

所以我们从最简单的 ans = [1] 开始推导,构造奇数 [(2*i-1) for i in ans] + 偶数 [2*i for i in ans]拼接在一起成为新的美丽数组;如果当前构造的美丽数组的长度小于 N,就继续这个操作,就能使得得到的一直是美丽数组。因为每次构造的美丽数组的长度是 2 的整数次方,所以最后要把结果中小于等于 N 的留下来,大于 N 的数字删除即可(性质 4)。

因为构造的美丽数组的长度是随着 2 的整数次方增长的,因此外层循环是 O(logN) 级别,内层循环是 O(N) 级别,总时间复杂度为 O(N*logN);空间复杂度为 O(N)。

Python3 实现:
class Solution:
    def beautifulArray(self, N: int) -> List[int]:
        ans = [1]  # 从[1]开始构造
        while len(ans) < N:  # 美丽数组长度小于N
            ans = [(2 * i -1) for i in ans] + [(2 * i) for i in ans]  # 性质2、3、5
        return [i for i in ans if i <= N]  # 性质4
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容