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("}\n"); 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\n",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.\n"); 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 };