1718. Construct the Lexicographically Largest Valid Sequence

问题:

给定一个数字n

则有一个1,从2~n各个数字两个。

进行排序,使得除了1之外任意两个相同数字直接的距离=数字自己。

得到一个字母序最大的解。

Example 1:
Input: n = 3
Output: [3,1,2,3,2]
Explanation: [2,3,2,1,3] is also a valid sequence, but [3,1,2,3,2] is the lexicographically largest valid sequence.

Example 2:
Input: n = 5
Output: [5,3,1,4,3,5,2,4,2]
 
Constraints:
1 <= n <= 20

  

解法:Backtracking(回溯算法)

  • 状态:到目前为止,当前位置pos之前所得到选择的结果path
  • 选择:所有可用数字(用过两次的除外)
  • 递归退出条件:pos==path.size

⚠️  注意:单纯一个位置一个位置进行填入数字,会超时TLE

因此,

♻️ 优化:每次填入一个数字的同时,填入该数字的下一个位置pos+i。

⚠️ 注意:能填入的条件:pos+i<path.size 且,该位置没有被填入数字

否则,continue,进行下一个数字的选择。(⚠️ 注意:不是直接return,for进行下一个数字的选择)

由于同时填入pos+i位置的数字,因此,在进行该pos位置的选择之前,若该位置已经被填充,则进行下一个位置递归 pos+1

代码参考:

 1 class Solution {
 2 public:
 3 //    int count = 0;
 4 //    void print_intend() {
 5 //        for(int i=0; i<count; i++) {
 6 //            printf("  ");
 7 //        }
 8 //    }
 9 //    void printV(vector<int>& v) {
10 //        printf("{");
11 //        for(auto i:v) {
12 //            printf("%d,",i);
13 //        }
14 //        printf("}
");
15 //    }
16     void backtrack(vector<int>& res, vector<int>& path, int pos, vector<bool>& used) {
17         if(pos == path.size()) {
18             res = path;
19 //            print_intend();
20 //            printf("res=");printV(res);
21 //            print_intend();
22 //            printf("path=");printV(path);
23             return;
24         }
25         if(path[pos]!=0) backtrack(res, path, pos+1, used);
26         else {
27             for(int i=used.size()-1; i>0; i--) {
28                 if(!used[i]){
29  //               print_intend();
30  //               printf("pos+i=%d,path.size()=%d,",pos+i,path.size());
31  //               if(pos+i<path.size())printf("path[pos+i]=%d
",path[pos+i]);
32                     if(i!=1 && ((pos+i) >= path.size() || path[pos+i]!=0)) continue;
33                     if(i!=1 && path[pos+i]==0) path[pos+i] = i;
34                     used[i] = true;
35                     path[pos] = i;
36  //                   count++;
37                 //print_intend();
38                 //printf("used=");printV(used);
39                // print_intend();
40                // printf("pos=%d, path=",pos);printV(path);
41                     backtrack(res, path, pos+1, used);
42   //                  count--;
43                     path[pos] = 0;
44                     if(i!=1) path[pos+i] = 0;
45                     used[i] = false;
46                     if(!res.empty()) return;
47                 }
48             }
49         }
50         
51            // print_intend();
52            // printf("Try end all.
");
53         return;
54     }
55     vector<int> constructDistancedSequence(int n) {
56         vector<bool> used(n+1, false);
57         vector<int> res;
58         vector<int> path(2*n-1, 0);
59         backtrack(res, path, 0, used);
60         return res;
61     }
62 };
原文地址:https://www.cnblogs.com/habibah-chang/p/14430749.html