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 ...
随机推荐
- MongoDB基操
基本概念 database 数据库 包含多个collection collection 集合 包含多个文档document(类JSON对象) document 文档 一个文档对象中包含多个key-va ...
- NYOJ 747贪心+dp
蚂蚁的难题(三) 时间限制:2000 ms | 内存限制:65535 KB 难度:4 描述 蚂蚁终于把尽可能多的食材都搬回家了,现在开始了大厨计划. 已知一共有 n 件食材,每件食材有一个美味 ...
- tp查找某字段,排除某字段,不用一次写那么多
更多的情况下我们都是查询某些字段,但有些情况下面我们需要通过字段排除来更方便的查询字段,例如文章详细页,我们可能只需要排除status和update_time字段,这样就不需要写一堆的字段名称了(有些 ...
- js获取当前页面的参数,带完善~~~
let url = window.location.href; let id = url.slice(url.indexOf('?') + 4);
- 解决iText2.0.8+freemark导出pdf不支持base64的解决办法
转换工具类 public class B64ImgReplacedElementFactory implements ReplacedElementFactory { /** * 实现createRe ...
- 【Tools】Windows下Github的配置和使用
1.在网址:http://windows.github.com/下载git软件,具体的安装步骤可以参见:Windows 系统下Git安装图解 2.同样根据上面的教程生成SSH key: 3.将publ ...
- tcp/ip 学习-通过视频学习
视频下载地址:http://down.51cto.com/zt/5518/ http://www.icoolxue.com/album/show/328 每天可以拿两个番茄钟看视频,主要目的还是了解, ...
- 【C++对象模型】第三章 Data语义学
1. Data Member 的布局 同一个Access Section(private, public等)中,data member的顺序按照声明顺序排列,但是没有规定需要连续排序.同时编译器可能会 ...
- 如何设计一个优雅健壮的Android WebView?(下)
转:如何设计一个优雅健壮的Android WebView?(下) 前言 在上文<如何设计一个优雅健壮的Android WebView?(上)>中,笔者分析了国内WebView的现状,以及在 ...
- 密码本(无bug版)
main.cpp #include <stdio.h> #include <stdlib.h> #include "data.h" #include &qu ...