@@ -82,32 +82,200 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3900-3999/3955.Va
8282
8383<!-- solution:start -->
8484
85- ### 方法一
85+ ### 方法一:DFS
86+
87+ 我们希望生成长度为 $n$ 的二进制字符串,并满足:
88+
89+ - 每个 ` 1 ` 的位置 $i$(从 $0$ 开始)累加的总和不超过 $k$,即
90+
91+
92+ $$
93+ \sum_{i \mid s_i = 1} i \le k
94+ $$
95+
96+ - 任意连续的 ` 1 ` 不能直接相邻。
97+
98+ 因此,我们设计一个递归函数 $\text{dfs}(i, tot)$,表示:
99+
100+ - 当前处理到字符串的第 $i$ 个位置;
101+ - 当前已经放置的所有 ` 1 ` 的下标之和为 $tot$。
102+
103+ #### 递归逻辑
104+
105+ ** 1. 递归终止条件**
106+
107+ 当 $i \ge n$ 时,说明长度为 $n$ 的字符串已经构造完成,将当前路径加入答案。
108+
109+ ** 2. 选择 ` 0 ` **
110+
111+ 当前位置始终可以放置 ` 0 ` ,递归调用 $\text{dfs}(i + 1, tot)$,由于当前位置放置的是 ` 0 ` ,因此总和不发生变化。
112+
113+ ** 3. 选择 ` 1 ` **
114+
115+ 只有同时满足以下两个条件时,当前位置才能放置 ` 1 ` :前一个字符不存在或为 ` 0 ` 并且 $tot + i \le k$。此时递归调用 $\text{dfs}(i + 1, tot + i)$。
116+
117+ ** 4. 回溯**
118+
119+ 每次递归返回后,撤销当前选择,恢复到进入递归前的状态,从而继续搜索其他可能的方案。
120+
121+ 时间复杂度 $O(n \times 2^n)$,空间复杂度 $O(n)$。
86122
87123<!-- tabs:start -->
88124
89125#### Python3
90126
91127``` python
92-
128+ class Solution :
129+ def generateValidStrings (self , n : int , k : int ) -> list[str ]:
130+ def dfs (i : int , tot : int ):
131+ if i >= n:
132+ ans.append(" " .join(path))
133+ return
134+ path.append(" 0" )
135+ dfs(i + 1 , tot)
136+ path.pop()
137+ if (not path or path[- 1 ] == " 0" ) and tot + i <= k:
138+ path.append(" 1" )
139+ dfs(i + 1 , tot + i)
140+ path.pop()
141+
142+ ans = []
143+ path = []
144+ dfs(0 , 0 )
145+ return ans
93146```
94147
95148#### Java
96149
97150``` java
98-
151+ class Solution {
152+ private int n;
153+ private int k;
154+ private List<String > ans;
155+ private StringBuilder path;
156+
157+ public List<String > generateValidStrings (int n , int k ) {
158+ this . n = n;
159+ this . k = k;
160+ ans = new ArrayList<> ();
161+ path = new StringBuilder ();
162+
163+ dfs(0 , 0 );
164+
165+ return ans;
166+ }
167+
168+ private void dfs (int i , int tot ) {
169+ if (i >= n) {
170+ ans. add(path. toString());
171+ return ;
172+ }
173+
174+ path. append(' 0' );
175+ dfs(i + 1 , tot);
176+ path. deleteCharAt(path. length() - 1 );
177+
178+ if ((path. isEmpty() || path. charAt(path. length() - 1 ) == ' 0' ) && tot + i <= k) {
179+ path. append(' 1' );
180+ dfs(i + 1 , tot + i);
181+ path. deleteCharAt(path. length() - 1 );
182+ }
183+ }
184+ }
99185```
100186
101187#### C++
102188
103189``` cpp
104-
190+ class Solution {
191+ public:
192+ vector<string > generateValidStrings(int n, int k) {
193+ vector<string > ans;
194+ string path;
195+
196+ auto dfs = [&](this auto&& dfs, int i, int tot) -> void {
197+ if (i >= n) {
198+ ans.push_back(path);
199+ return;
200+ }
201+
202+ path.push_back(' 0' );
203+ dfs (i + 1, tot);
204+ path.pop_back();
205+
206+ if ((path.empty() || path.back() == '0') && tot + i <= k) {
207+ path.push_back('1');
208+ dfs(i + 1, tot + i);
209+ path.pop_back();
210+ }
211+ };
212+
213+ dfs(0, 0);
214+
215+ return ans;
216+ }
217+ };
105218```
106219
107220#### Go
108221
109222```go
223+ func generateValidStrings(n int, k int) []string {
224+ ans := []string{}
225+ path := make([]byte, 0, n)
226+
227+ var dfs func(int, int)
228+ dfs = func(i, tot int) {
229+ if i >= n {
230+ ans = append(ans, string(path))
231+ return
232+ }
233+
234+ path = append(path, '0')
235+ dfs(i+1, tot)
236+ path = path[:len(path)-1]
237+
238+ if (len(path) == 0 || path[len(path)-1] == '0') && tot+i <= k {
239+ path = append(path, '1')
240+ dfs(i+1, tot+i)
241+ path = path[:len(path)-1]
242+ }
243+ }
244+
245+ dfs(0, 0)
246+
247+ return ans
248+ }
249+ ```
250+
251+ #### TypeScript
252+
253+ ``` ts
254+ function generateValidStrings(n : number , k : number ): string [] {
255+ const ans: string [] = [];
256+ const path: string [] = [];
257+
258+ const dfs = (i : number , tot : number ): void => {
259+ if (i >= n ) {
260+ ans .push (path .join (' ' ));
261+ return ;
262+ }
263+
264+ path .push (' 0' );
265+ dfs (i + 1 , tot );
266+ path .pop ();
267+
268+ if ((path .length === 0 || path [path .length - 1 ] === ' 0' ) && tot + i <= k ) {
269+ path .push (' 1' );
270+ dfs (i + 1 , tot + i );
271+ path .pop ();
272+ }
273+ };
274+
275+ dfs (0 , 0 );
110276
277+ return ans ;
278+ }
111279```
112280
113281<!-- tabs:end -->
0 commit comments