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:

  1. Insert a character
  2. Delete a character
  3. 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) }

  1. f(i, j - 1) represents insert operation
  2. f(i - 1, j) represents delete operation
  3. 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的更多相关文章

  1. LeetCode解题报告:Linked List Cycle && Linked List Cycle II

    LeetCode解题报告:Linked List Cycle && Linked List Cycle II 1题目 Linked List Cycle Given a linked ...

  2. leetcode解题报告(2):Remove Duplicates from Sorted ArrayII

    描述 Follow up for "Remove Duplicates": What if duplicates are allowed at most twice? For ex ...

  3. LeetCode 解题报告索引

    最近在准备找工作的算法题,刷刷LeetCode,以下是我的解题报告索引,每一题几乎都有详细的说明,供各位码农参考.根据我自己做的进度持续更新中......                        ...

  4. leetCode解题报告5道题(六)

    题目一: Longest Substring Without Repeating Characters Given a string, find the length of the longest s ...

  5. LeetCode解题报告—— Trapping Rain Water

    Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...

  6. LeetCode解题报告—— Longest Valid Parentheses

    Given a string containing just the characters '(' and ')', find the length of the longest valid (wel ...

  7. 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 ...

  8. 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 ...

  9. 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 ...

随机推荐

  1. AOJ.863 分书问题 (DFS)

    题意分析 现有n个人,n种书,给出每人对n种书的喜欢列表,求有多少种方案满足以下条件: 1.每个人都分得自己喜欢的书: 2.每个人分得书的种类各不相同,即所有种类的书均得到分配 1.采用生成测试法 生 ...

  2. bzoj3680: 吊打XXX(模拟退火)

    题目要求 最小(dis表示绳结到点i的距离),就是个广义费马点的题,模拟退火裸题QAQ 模拟退火就是优化后的爬山算法,一开始先随机一个平均点,接下来如果随机到的点比当前点劣,温度比较高的话也有几率跳过 ...

  3. Python图像处理库(PIL)

    官方:(详细)http://pillow.readthedocs.io/en/3.1.x/reference/ImageDraw.html http://pillow.readthedocs.io/e ...

  4. HDU1024 最大m子段和

    Max Sum Plus Plus Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others ...

  5. SoC时钟系统简介

    1.SoC的时钟获得一般有: * 外部直接输入时钟信号,SoC有个引脚用来输入外部时钟信号,用的很少. * 外部晶振+内部时钟发生器产生时钟,大部分低频单片机都是这么工作的. * 外部晶振+内部时钟发 ...

  6. 安卓弹出键盘隐藏fixed定位相关的元素(obj必须是class)

    //安卓弹出键盘隐藏fixed定位相关的元素(obj必须是class) function displayFixed(obj){ var h = document.body.scrollHeight; ...

  7. MyBatis框架的使用及源码分析(五) DefaultSqlSessionFactory和DefaultSqlSession

    我们回顾<MyBatis框架中Mapper映射配置的使用及原理解析(一) 配置与使用> 一文的示例 private static SqlSessionFactory getSessionF ...

  8. 使用Docker搭建Django,Nginx,R,Python部署环境

    转载自https://blog.csdn.net/The_One_is_all/article/details/76063968 基本环境: Ubuntu 16.10 docker 17.06.0-c ...

  9. 阿里云maven仓库地址,速度提升100倍

    参照:https://www.cnblogs.com/xxt19970908/p/6685777.html maven仓库用过的人都知道,国内有多么的悲催.还好有比较好用的镜像可以使用,尽快记录下来. ...

  10. 【BZOJ】1699 [Usaco2007 Jan]Balanced Lineup排队

    [算法]线段树 #include<cstdio> #include<cctype> #include<algorithm> using namespace std; ...