diff --git a/content/posts/leetcode.md b/content/posts/leetcode.md index 90a276e..7b8aa28 100644 --- a/content/posts/leetcode.md +++ b/content/posts/leetcode.md @@ -23148,3 +23148,86 @@ private: }; ``` +## day343 2025-02-16 +### 1718. Construct the Lexicographically Largest Valid Sequence +Given an integer n, find a sequence that satisfies all of the following: + +The integer 1 occurs once in the sequence. +Each integer between 2 and n occurs twice in the sequence. +For every integer i between 2 and n, the distance between the two occurrences of i is exactly i. +The distance between two numbers on the sequence, a[i] and a[j], is the absolute difference of their indices, |j - i|. + +Return the lexicographically largest sequence. It is guaranteed that under the given constraints, there is always a solution. + +A sequence a is lexicographically larger than a sequence b (of the same length) if in the first position where a and b differ, sequence a has a number greater than the corresponding number in b. For example, [0,1,9,0] is lexicographically larger than [0,1,5,6] because the first position they differ is at the third number, and 9 is greater than 5. + +![0216SDt6Dx6RnsIF](https://testingcf.jsdelivr.net/gh/game-loader/picbase@master/uPic/0216SDt6Dx6RnsIF.png) + +### 题解 +本题根据题目条件,由于数字的两次出现的间隔固定,确定了一个数字的第一个位置就相当于确定了该数字的两个出现位置。因此对于任意一个位置可以尝试从大到小依次安排数字,在安排了一个数字后即可确定数字的另外一个位置,用一个数组保存位置的占用状态,使用回溯算法判断不同组合的可行性,因为对于任何一个位置安置数字时都是尝试从大到小安排数字的,则一旦找到一个可行的组合就是字典序最大的组合。 + +具体来说,在第i个位置尝试放置一个数字后,使用递归算法尝试安置下一个位置,调用递归算法时传入数组的位置占用状态和剩余的可用数字。尝试安置数字,安置数字时根据位置占用状态判断数字是否能否被安置在当前位置,若所有可用数字均不能安置在当前位置则返回false。考虑n最大为20,此处数组的位置占用状态(可根据n计算出数组长度)和剩余的可用数字均可使用数组保存。 + + +### 代码 +```cpp +class Solution { +public: + vector constructDistancedSequence(int n) { + vector result(2 * n - 1, 0); + vector occupied(2 * n - 1, false); + vector used(n + 1, false); + + solve(0, n, result, occupied, used); + + return result; + } + +private: + bool solve(int index, int n, vector& result, vector& occupied, vector& used) { + if (index == result.size()) { + return true; + } + + if (occupied[index]) { + return solve(index + 1, n, result, occupied, used); + } + + for (int i = n; i >= 1; --i) { + if (used[i]) { + continue; + } + + int secondIndex = index + (i == 1 ? 0 : i); + + if (i != 1 && (secondIndex >= result.size() || occupied[secondIndex])) { + continue; + } + + result[index] = i; + occupied[index] = true; + used[i] = true; + + if (i != 1) { + result[secondIndex] = i; + occupied[secondIndex] = true; + } + + if (solve(index + 1, n, result, occupied, used)) { + return true; + } + + result[index] = 0; + occupied[index] = false; + used[i] = false; + + if (i != 1) { + result[secondIndex] = 0; + occupied[secondIndex] = false; + } + } + return false; + } +}; +``` +