LeetCode解题报告—— N-Queens && Edit Distance
1. N-Queens
The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens attack each other.

Given an integer n, return all distinct solutions to the n-queens puzzle.
Each solution contains a distinct board configuration of the n-queens' placement, where 'Q' and '.' both indicate a queen and an empty space respectively.
Example:
Input: 4
Output: [
[".Q..", // Solution 1
"...Q",
"Q...",
"..Q."], ["..Q.", // Solution 2
"Q...",
"...Q",
".Q.."]
]
Explanation: There exist two distinct solutions to the 4-queens puzzle as shown above.
思路
尝试以回溯来解题,结果还是做不下去。分析下别人的答案,果然回溯是可以解这道题的。回溯的思路不对,把数独那题的解法照搬到这题上来了,事实上的确有相似的部分,但是完全照搬果然是不行的。
自己用回溯来解的时候发现两个比较麻烦的问题,一是这题要求解的是所有可能的组合,即正确的组合可能有多个,其次是如何判断两个斜对角线上的问题把我搞晕了,算法真的好难,好难,好难。
代码:
class Solution {
public List<List<String>> solveNQueens(int n) {
List<List<String>> res=new ArrayList();
char[][] chessboard=new char[n][n];
for(int i=0;i<n;i++){ // 这里曾尝试用foreach来赋初始值,结果不对
for(int j=0;j<n;j++){
chessboard[i][j]='.';
}
}
solve(res, chessboard, 0, n);
return res;
}
void solve(List<List<String>> res, char[][] chessboard, int row, int n){
if(row==n){
List<String> ls=new ArrayList();
for(int i=0; i<n; i++){
ls.add(new String(chessboard[i]));
}
res.add(ls);
return;
}
for(int col=0; col<n; col++){
if(isValid(chessboard, row, col, n)){
chessboard[row][col]='Q';
solve(res, chessboard, row+1, n); // 逐行放置确保行合法,不需要再作额外判断
chessboard[row][col]='.';
}
}
}
boolean isValid(char[][] chessboard, int row, int col, int n){
for(int i=0;i<row;i++){ // 判断当前列有没有Q,注意这里只需要判断当前行之前的列那部分就可以了,不需要全部判断!
if(chessboard[i][col]=='Q') return false;
}
for(int i=row-1, j=col-1; i>=0 && j>=0;i--,j--){ // 45度斜对角线,和上面一样只需要判断之前的部分
if(chessboard[i][j]=='Q') return false;
}
for(int i=row-1, j=col+1; i>=0 && j<n;i--,j++){ // 135度对角线
if(chessboard[i][j]=='Q') return false;
}
return true;
}
}
要注意的上面那个isValid判断,每次判断合法不是一次性判断整行整列,而是和它之前确定的部分判断,只要放置之前不和之前放置的冲突就能确保每次放置后的棋盘是合法的。
2. Edit Distance
Given two words word1 and word2, find the minimum number of operations required to convert word1 to word2.
You have the following 3 operations permitted on a word:
- Insert a character
- Delete a character
- Replace a character
Example 1:
Input: word1 = "horse", word2 = "ros"
Output: 3
Explanation:
horse -> rorse (replace 'h' with 'r')
rorse -> rose (remove 'r')
rose -> ros (remove 'e')
Example 2:
Input: word1 = "intention", word2 = "execution"
Output: 5
Explanation:
intention -> inention (remove 't')
inention -> enention (replace 'i' with 'e')
enention -> exention (replace 'n' with 'x')
exention -> exection (replace 'n' with 'c')
exection -> execution (insert 'u')
思路
又是一道dp可以求解的题目,然而又不会建dp模型。
f(i, j) = minimum cost (or steps) required to convert first i characters of word1 to first j characters of word2
Case 1: word1[i] == word2[j], i.e. the ith the jth character matches.
f(i, j) = f(i - 1, j - 1)
Case 2: word1[i] != word2[j], then we must either insert, delete or replace, whichever is cheaper
f(i, j) = 1 + min { f(i, j - 1), f(i - 1, j), f(i - 1, j - 1) }
- f(i, j - 1) represents insert operation
- f(i - 1, j) represents delete operation
- f(i - 1, j - 1) represents replace operation
Here, we consider any operation from word1 to word2. It means, when we say insert operation, we insert a new character after word1 that matches the jth character of word2. So, now have to match i characters of word1 to j - 1 characters of word2. Same goes for other 2 operations as well.
Note that the problem is symmetric. The insert operation in one direction (i.e. from word1 to word2) is same as delete operation in other. So, we could choose any direction.
Above equations become the recursive definitions for DP.
Base Case:
f(0, k) = f(k, 0) = k
没什么好说的了,还是慢慢累积dp经验吧。不过现在有点感觉是,和之前那个字符串模式串匹配的dp类似,这种类字符串之间匹配,转化的问题在考虑子问题之间的联系(求地推公式)时,都是从字符串的最右边字符开始考虑,现在想起来求公共最长字串的dp好像也是这样,考虑子问题中两个字符串的最右边字符是否相等的情况,然后就得出了地推公式......,不知道这能否能通用起来。
代码:
class Solution {
public int minDistance(String word1, String word2) {
int[][] dp=new int[word1.length()+1][word2.length()+1];
for(int i=0;i<=word2.length();i++){
dp[0][i]=i;
}
for(int i=0;i<=word1.length();i++){
dp[i][0]=i;
}
for(int i=1;i<=word1.length();i++){
for(int j=1;j<=word2.length();j++){
if(word1.charAt(i-1)==word2.charAt(j-1)){
dp[i][j]=dp[i-1][j-1];
}else{
int min=Math.min(dp[i][j-1], dp[i-1][j]);
dp[i][j]=Math.min(min+1, dp[i-1][j-1]+1);
}
}
}
return dp[word1.length()][word2.length()];
}
}
LeetCode解题报告—— N-Queens && Edit Distance的更多相关文章
- LeetCode解题报告:Linked List Cycle && Linked List Cycle II
LeetCode解题报告:Linked List Cycle && Linked List Cycle II 1题目 Linked List Cycle Given a linked ...
- leetcode解题报告(2):Remove Duplicates from Sorted ArrayII
描述 Follow up for "Remove Duplicates": What if duplicates are allowed at most twice? For ex ...
- LeetCode 解题报告索引
最近在准备找工作的算法题,刷刷LeetCode,以下是我的解题报告索引,每一题几乎都有详细的说明,供各位码农参考.根据我自己做的进度持续更新中...... ...
- leetCode解题报告5道题(六)
题目一: Longest Substring Without Repeating Characters Given a string, find the length of the longest s ...
- LeetCode解题报告—— Trapping Rain Water
Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...
- LeetCode解题报告—— Longest Valid Parentheses
Given a string containing just the characters '(' and ')', find the length of the longest valid (wel ...
- LeetCode解题报告—— Search in Rotated Sorted Array & Search for a Range & Valid Sudoku
1. Search in Rotated Sorted Array Suppose an array sorted in ascending order is rotated(轮流,循环) at so ...
- LeetCode解题报告—— 2 Keys Keyboard & Longest Palindromic Substring & ZigZag Conversion
1. Longest Palindromic Substring Given a string s, find the longest palindromic substring in s. You ...
- LeetCode解题报告—— 1-bit and 2-bit Characters & 132 Pattern & 3Sum
1. 1-bit and 2-bit Characters We have two special characters. The first character can be represented ...
随机推荐
- CodeForces.5A Chat Server's Outgoing Traffic
Chat Server's Outgoing Traffic 点我挑战提目 考察点 模拟 字符串 Time Mem Len Lang 30 0 543 c++ 题意分析 给出类似一个群的即时通讯系统, ...
- Jokewithpermutation (DFS)
Problem J. Jokewithpermutation Input file: joke.inOutput file: joke.out Joey had saved a permutation ...
- JQuery学习三(隐式迭代和节点遍历)
在JQuery中根据id获取控件,如果输入id错误是不报错的. 必要时可以通过写判断语句进行判断是否id写错 <!DOCTYPE html> <html xmlns="ht ...
- Git版本管理1-安装配置和同步
原文载于youdaonote,有图片: http://note.youdao.com/share/?id=79a2d4cae937a97785bda7b93cbfc489&type=note ...
- [技巧篇]08.Struts2拦截器中获取Servlet API方法
讲课中遇到的解决Session拦截器的后腿问题,还有如何在拦截器中获取Servlet API,这里留一个备注,方便学生查找
- Eclipse中安装插件的三种方式
转载自:http://www.cnblogs.com/lcgustc/archive/2013/01/03/2843496.html Eclipse也用了很久,但是都没有怎么去研究过怎么安装插件,今天 ...
- [LeetCode] Simplify Path,文件路径简化,用栈来做
Given an absolute path for a file (Unix-style), simplify it. For example,path = "/home/", ...
- 【JAVA】Pattern和Matcher
ZZ: Java正则表达式:Pattern类和Matcher类 一.捕获组的概念 捕获组可以通过从左到右计算其开括号来编号,编号是从1 开始的.例如,在表达式 ((A)(B(C)))中,存在四个这样的 ...
- PowerDesigner16 把设计图导出成图片
1. 用鼠标选择要导出的对象,必须先选择. 2. 选择Edit—>Export Image 导出为你需要的格式图片,见下图:
- Linux Shell下执行sqlplus
转载自: http://www.cnblogs.com/include/archive/2011/12/30/2307889.html 以下方法解决了在linux下自动的删除创建用户 sqlplus ...