1.括號生成
數字 n 代表生成括號的對數,請你設計一個函數,用於能夠生成所有可能的並且 有效的括號組合。
例如,給出 n = 3,生成結果爲:
[ "((()))", "(()())", "(())()", "()(())", "()()()" ]
思路:
有效括號的條件:每個左括號都有一個右括號與之匹配
(1)通過dfs每次插入一個括號,並記錄剩餘左右括號的個數
(2)當剩餘左括號比剩餘右括號多時,必然有左括號在後面插入後無法匹配,直接返回
(3)左右括號個數都使用完時,將字符串存入數組。
var generateParenthesis = function (n) {
let ans = [];
const dfs = (left, right, str) => {
if (left > right) return;/* 左邊有無法匹配的 */
if (!left && !right) {
ans.push(str);
return;
}
if (left) dfs(left - 1, right, str + '(');
if (right) dfs(left, right - 1, str + ')');
}
dfs(n, n, '');
return ans;
};
2.N皇后問題
n 皇后問題研究的是如何將 n 個皇后放置在 n×n 的棋盤上,並且使皇后彼此之間不能相互攻擊。
給定一個整數 n,返回所有不同的 n 皇后問題的解決方案。
輸入: 4
輸出: [
[".Q..", // 解法 1
"...Q",
"Q...",
"..Q."],
["..Q.", // 解法 2
"Q...",
"...Q",
".Q.."]
]
解釋: 4 皇后問題存在兩個不同的解法。
思路:
放置皇后的座標需要具備的條件:
(1)不能和前面放置的皇后在同一列 y2!=y1
(2)不能和前面放置的皇后在同一對角線,|x2-x1|!=|y2-y1|
dfs按照層數選取放置位置(按照上述兩個條件判斷所便利的位置是否可以放置),用position存各層放置的座標,所有皇后已經放置完則將position記錄的聯繫轉化到字符串,存入數組即可。
var solveNQueens = function (n) {
let ans = [];
var isValid = (x, y, position) => {
/* 遍歷x前面已經放置的層數 */
for (let prex = 0; prex < x; prex++) {
if (position[prex] === y)/* y列已經放置過 */
return false;
/* 在對角線上 */
if (Math.abs(x - prex) === Math.abs(y - position[prex]))
return false;
}
return true;
}
var getString = position => {
let res = [];
for (let i = 0; i < n; i++) {
res[i] = '';
for (let j = 0; j < n; j++) {
res[i] += position[i] === j ? 'Q' : '.';
}
}
return res;
}
var dfs = (x, position) => {
if (x == n) {/* 全部已經放置完 */
ans.push(getString(position));
return;
}
for (let y = 0; y < n; y++) {
if (isValid(x, y, position)) {/* 判斷(x,y)是否能放 */
position[x] = y;
dfs(x + 1, position);
}
}
}
dfs(0, []);
};
3.復原ip地址
給定一個只包含數字的字符串,復原它並返回所有可能的 IP 地址格式。
輸入: "25525511135"
輸出: ["255.255.11.135", "255.255.111.35"]
步驟:
(1)dfs每次切割1-3個字符形成串tmp
,將切割的字符串存入數組arr
切割字符串符合的條件:
a.一位且轉化爲數字是0 ->tmp==='0'
b.轉化爲數字大小在[1,256]範圍內不能有前導零->parseInt(tmp) > 0 && parseInt(tmp) < 256
(2)將剩餘字符串str.substr(i)
和數組arr
穿給下一層繼續選擇切割
(3)存滿4層,若此時str
爲空,說明所有字符都已經按照上述條件存入數組,利用join
將數組轉化爲字符串並在中間加入分隔符.
,存到Set中
(4)將Set轉化爲數組返回
var restoreIpAddresses = function (s) {
let ans = new Set();
const dfs = (str, arr, level) => {
if (level == 4) {
if (!str)
ans.add(arr.join('.'));
return;
}
for (let i = 1; i <= Math.min(str.length, 3); i++) {
let tmp = str.substr(0, i);//切割前i個
if (tmp === '0' || tmp.charAt(0) != 0 && parseInt(tmp) > 0 && parseInt(tmp) < 256) {
arr[level] = tmp;
dfs(str.substr(i), arr, level + 1);/* str切割i個傳給下一層 */
}
}
}
dfs(s, [], 0);
return [...ans];
};