leetcode:查找
1. word ladder
题目:
Given two words (start and end), and a dictionary, find the length of shortest transformation sequence from start to end, such that:
- Only one letter can be changed at a time
- Each intermediate word must exist in the dictionary
For example,
Given:
start = "hit"
end = "cog"
dict = ["hot","dot","dog","lot","log"]
As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog",
return its length 5.
Note:
- Return 0 if there is no such transformation sequence.
- All words have the same length.
- All words contain only lowercase alphabetic characters.
题解:
这道题是套用BFS同时也利用BFS能寻找最短路径的特性来解决问题 。所有的变化情况联系起来就是一棵树, 相当于从根结点start出发寻找特定的节点end。
把每个单词作为一个node进行BFS。当取得当前字符串时,对他的每一位字符进行从a~z的替换,如果在字典里面,就入队,并将下层count++,并且为了避免环路,需把在字典里检测到的单词从字典里删除。这样对于当前字符串的每一位字符安装a~z替换后,在queue中的单词就作为下一层需要遍历的单词了。
正因为BFS能够把一层所有可能性都遍历了,所以就保证了一旦找到一个单词equals(end),那么return的路径肯定是最短的。
像给的例子 start = hit,end = cog,dict = [hot, dot, dog, lot, log]
按照上述解题思路的走法就是:
level = 1 hit dict = [hot, dot, dog, lot, log]
ait bit cit ... xit yit zit , hat hbt hct ... hot ... hxt hyt hzt , hia hib hic ... hix hiy hiz
level = 2 hot dict = [dot, dog, lot, log]
aot bot cot dot ... lot ... xot yot zot,hat hbt hct ... hxt hyt hzt,hoa hob hoc ... hox hoy hoz
level = 3 dot lot dict = [dog log]
aot bot ... yot zot,dat dbt ...dyt dzt,doa dob ... dog .. doy doz,
aot bot ... yot zot,lat lbt ... lyt lzt,loa lob ... log... loy loz
level = 4 dog log dict = []
aog bog cog
level = 5 cog dict = []
public int ladderLength(String start, String end, HashSet<String> dict) {
if(start==null || end==null || start.length()==0 || end.length()==0 || start.length()!=end.length())
return 0;
LinkedList<String> wordQueue = new LinkedList<String>();
int level = 1; //the start string already count for 1
int curnum = 1;//the candidate num on current level
int nextnum = 0;//counter for next level
//一个单词变换一个字母后可能有多个符合条件的单词,即多个子节点
wordQueue.add(start);
while(!wordQueue.isEmpty()){
//poll移除并返问队列头部的元素;
//peek返回队列头部的元素;
String word = wordQueue.poll();
curnum--;
for(int i = 0; i < word.length(); i++){
char[] wordunit = word.toCharArray();
for(char j = 'a'; j <= 'z'; j++){
//字符串不可修改,转换成字符数组
wordunit[i] = j;
String temp = new String(wordunit);
if(temp.equals(end))
return level+1;
if(dict.contains(temp)){
wordQueue.add(temp);
nextnum++;
dict.remove(temp);
}
}
}
if(curnum == 0){
curnum = nextnum;
nextnum = 0;
level++;
}
}
return 0;
}
2. 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.
For example,
There exist two distinct solutions to the 4-queens puzzle:
[
[".Q..", // Solution 1
"...Q",
"Q...",
"..Q."], ["..Q.", // Solution 2
"Q...",
"...Q",
".Q.."]
]
题解:
经典的DFS递归回溯解法,大体思路就是对每一行,按每一列挨个去试,试到了就保存结果没试到就回溯。
难点大概就是用1个一维数组存皇后所在的坐标值。对于一个棋盘来说,每个点都有横纵坐标,用横纵坐标可以表示一个点。
而这道题巧就巧在,每一行只能有一个皇后,也就是说,对于一行只能有一个纵坐标值,所以用1维数组能提前帮助解决皇后不能在同一行的问题。
那么用一维数组表示的话,方法是:一维数组的下标表示横坐标(哪一行),而数组的值表示纵坐标(哪一列)。 例如:对于一个4皇后问题,声明一个长度为4的数组(因为行数为4)。
A[] = [1,0,2,3]表达含义是:
当前4个皇后所在坐标点为:[[0,1],[1,0],[2,2],[3,3]](被我标蓝的正好是数组的下标,标粉的正好是数组的值)
相当于:A[0] = 1, A[1] = 0, A[2] = 2, A[3] = 3 这样以来,皇后所在的坐标值就能用一维数组表示了。
而正是这个一维数组,在回溯找结果的时候不需要进行remove重置操作了,因为回溯的话正好就回到上一行了,就可以再重新找下一个合法列坐标了。 因为是按照每一行去搜索的,当行坐标值等于行数时,说明棋盘上所有行都放好皇后了,这时就把有皇后的位置标为Q,没有的地方标为0。
按照上面讲的那个一维数组,我们就可以遍历整个棋盘,当坐标为(row,columnVal[row])的时候,就说明这是皇后的位置,标Q就行了。
public ArrayList<String[]> solveNQueens(int n) {
ArrayList<String[]> res = new ArrayList<String[]>();
if(n<=0)
return res;
int [] columnVal = new int[n];
DFS_helper(n,res,0,columnVal);
return res;
}
public void DFS_helper(int nQueens, ArrayList<String[]> res, int row, int[] columnVal){
//row是当前测试的行号,row=nQueens时测试完毕
if(row == nQueens){
String[] unit = new String[nQueens];
for(int i = 0; i < nQueens; i++){
StringBuilder s = new StringBuilder();
for(int j = 0; j < nQueens; j++){
if(j == columnVal[i])
s.append("Q");
else
s.append(".");
}
//将StringBuilder转换为String
unit[i] = s.toString();
}
res.add(unit);
}else{
for(int i = 0; i < nQueens; i++){
//columnVal[] 存放位置,即第row行,第i列
columnVal[row] = i;
if(isValid(row,columnVal))
DFS_helper(nQueens, res, row+1, columnVal);
}
}
}
//判断新加入的row行那个queen是否和之前所有行的queen冲突
public boolean isValid(int row, int [] columnVal){
for(int i = 0; i < row; i++){
//因为采用一维数组存储,所以不需要比较是否在同一行(每行只有一个元素)
if(columnVal[row] == columnVal[i] //在同一列
||Math.abs(columnVal[row]-columnVal[i]) == row-i) //在对角线
return false;
}
return true;
}
3. word search
题目 :
Given a 2D board and a word, find if the word exists in the grid.
The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once.
For example,
Given board =
[
["ABCE"],
["SFCS"],
["ADEE"]
]
word = "ABCCED" , -> returns true ,
word = "SEE" , -> returns true ,
word = "ABCB" , -> returns false .
题解 :
这道题分析看,就是一个词,在一行出现也是true,一列出现也是true,一行往下拐弯也是true,一行往上拐弯也是true,一列往左拐弯也是true,一列往右拐弯也是true。所以是要考虑到所有可能性,基本思路是使用DFS来对一个起点字母上下左右搜索,看是不是含有给定的Word。还要维护一个visited数组,表示从当前这个元素是否已经被访问过了,过了这一轮visited要回false,因为对于下一个元素,当前这个元素也应该是可以被访问的。
public class Solution {
private int row;
private int col;
public boolean exist(char[][] board, String word) {
row = board.length;
col = board[0].length;
boolean[][] visited = new boolean[row][col];
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if (dfs(board, word, 0, i, j, visited))
return true;
}
}
return false;
}
private boolean dfs(char[][] board, String word, int index, int rowindex,
int colindex, boolean[][] visited) {
//index是已经匹配的字母长度
if (index == word.length())
return true;
if (rowindex < 0 || colindex < 0 || rowindex >= row || colindex >= col)
return false;
//visited记录该点是否已经被访问过
if (visited[rowindex][colindex])
return false;
//该处字母是否匹配要查找的word
if (board[rowindex][colindex] != word.charAt(index))
return false;
visited[rowindex][colindex] = true;
//四个方向至少有一个找到即可
boolean res = dfs(board, word, index + 1, rowindex - 1, colindex,
visited)
|| dfs(board, word, index + 1, rowindex + 1, colindex, visited)
|| dfs(board, word, index + 1, rowindex, colindex + 1, visited)
|| dfs(board, word, index + 1, rowindex, colindex - 1, visited);
//这轮完了。该点对于下一轮还是可以访问的
visited[rowindex][colindex] = false;
return res;
4.search for a rangr
题目:
Given a sorted array of integers, find the starting and ending position of a given target value.
Your algorithm's runtime complexity must be in the order of O(log n).
If the target is not found in the array, return [-1, -1].
For example,
Given [5, 7, 7, 8, 8, 10] and target value 8,
return [3, 4].
从题目中获取到关键字:sorted array ,find...position, a given target value, O(logn).
这些关键字都在提醒我们这道题的思路应该是二分查找法。
public class Solution {
public int searchStart(int[] A, int target) {
int start = 0, end = A.length - 1, result = -1, mid = 0;
while (start + 1 < end) {
mid = start + (end - start) / 2;
if(A[mid] > target) {
end = mid - 1;
} else if (A[mid] < target) {
start = mid + 1;
} else {
if(A[mid - 1] < target) {
return mid;
} else {
//此时mid, mid-1处的值都是target,mid-1之前也有可能是;
//通过end=mid,让其从左边向mid逼近,找到最左的target
end = mid;
}
}
}
if (A[start] == target) return start;
else if (A[end] == target) return end;
else return -1;
}
public int searchEnd(int[] A, int target) {
int start = 0, end = A.length - 1, result = -1, mid = 0;
while (start + 1 < end) {
mid = start + (end - start) / 2;
if(A[mid] > target) {
end = mid - 1;
} else if (A[mid] < target) {
start = mid + 1;
} else {
if(A[mid + 1] > target) {
return mid;
} else {
start = mid;
}
}
}
if (A[end] == target) return end;
else if (A[start] == target) return start;
else return -1;
}
public int[] searchRange(int[] A, int target) {
int [] result = new int[2];
result[0] = searchStart(A, target);
result[1] = searchEnd(A, target);
return result;
}
}
5. Combination sum
题目:
Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.
The same repeated number may be chosen from C unlimited number of times.
Note:
- All numbers (including target) will be positive integers.
- Elements in a combination (a1, a2, … , ak) must be in non-descending order. (ie, a1 ≤ a2 ≤ … ≤ ak).
- The solution set must not contain duplicate combinations.
For example, given candidate set 2,3,6,7 and target 7,
A solution set is: [7]
[2, 2, 3]
题解:
还是老问题,用DFS找解决方案,不同点是,这道题: The same repeated number may be chosen from Cunlimited number of times.
所以,每次跳进递归不用都往后挪一个,还可以利用当前的元素尝试。
同时,这道题还要判断重复解。
1. if(i>0 && candidates[i] == candidates[i-1])//deal with dupicate
continue;
2. if(!res.contains(item))
res.add(new ArrayList<Integer>(item));
这两个方法解决。
public ArrayList<ArrayList<Integer>> combinationSum(int[] candidates, int target) {
ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>();
ArrayList<Integer> item = new ArrayList<Integer>();
if(candidates == null || candidates.length==0)
return res;
Arrays.sort(candidates);
helper(candidates,target, 0, item ,res);
return res;
}
//res放置最后结果,target控制“层级”,通过修改target,不断向下一层搜索
private void helper(int[] candidates, int target, int start, ArrayList<Integer> item,
ArrayList<ArrayList<Integer>> res){
// 搜索的退出条件
if(target<0)
return;
if(target==0){
res.add(new ArrayList<Integer>(item));
return;
}
for(int i=start;i<candidates.length;i++){
if(i>0 && candidates[i] == candidates[i-1])//deal with dupicate
continue;
item.add(candidates[i]);
int newtarget = target - candidates[i];
helper(candidates,newtarget,i,item,res);//之所以不传i+1的原因是:
//The same repeated number may be
//chosen from C unlimited number of times.
item.remove(item.size()-1);
}
}
6. Letter Combinations of a Phone Number
Given a digit string, return all possible letter combinations that the number could represent.
A mapping of digit to letters (just like on the telephone buttons) is given below.
![]()
Input:Digit string "23"
Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].
Note:
Although the above answer is in lexicographical order, your answer could be in any order you want.
对数字进行解析,相当于遍历一棵树,使用DFS
public List<String> letterCombinations(String digits) {
HashMap<Integer, String> map = new HashMap<Integer, String>();
map.put(2, "abc");
map.put(3, "def");
map.put(4, "ghi");
map.put(5, "jkl");
map.put(6, "mno");
map.put(7, "pqrs");
map.put(8, "tuv");
map.put(9, "wxyz");
map.put(0, "");
ArrayList<String> result = new ArrayList<String>();
if(digits == null || digits.length() == 0)
return result;
ArrayList<Character> temp = new ArrayList<Character>();
getString(digits, temp, result, map);
return result;
}
public void getString(String digits, ArrayList<Character> temp, ArrayList<String> result, HashMap<Integer, String> map){
if(digits.length() == 0){
char[] arr = new char[temp.size()];
for(int i=0; i<temp.size(); i++){
arr[i] = temp.get(i);
}
result.add(String.valueOf(arr));
return;
}
/*str=str.substring(int beginIndex);
截取掉str从首字母起 长度为beginIndex的字符串,将剩余字符串赋值给str;
str=str.substring(int beginIndex,int endIndex);
截取str中从 下标beginIndex开始至endIndex-1结束时的字符串,并将其赋值给str;
*/
Integer curr = Integer.valueOf(digits.substring(0,1));
String letters = map.get(curr);
for(int i=0; i<letters.length(); i++){
temp.add(letters.charAt(i));
getString(digits.substring(1), temp, result, map);
temp.remove(temp.size()-1);
}
}
7. Generate Parentheses leetcode java
Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.
For example, given n = 3, a solution set is:
"((()))", "(()())", "(())()", "()(())", "()()()"
DFS递归解决
给定的n为括号对,所以就是有n个左括号和n个右括号的组合。
按顺序尝试知道左右括号都尝试完了就可以算作一个解。
注意,左括号的数不能大于右括号,要不然那就意味着先尝试了右括号而没有左括号,类似“)(” 这种解是不合法的。
public ArrayList<String> generateParenthesis(int n) {
ArrayList<String> res = new ArrayList<String>();
String item = new String();
if (n<=0)
return res;
dfs(res,item,n,n);
return res;
}
// item保存上一步的临时结果,res最终结果; leftt,right指示搜索层级变化
public void dfs(ArrayList<String> res, String item, int left, int right){
if(left > right)//deal wiith ")("
return;
if (left == 0 && right == 0){
res.add(new String(item));
return;
}
if (left>0)
dfs(res,item+'(',left-1,right);
if (right>0)
dfs(res,item+')',left,right-1);
}
leetcode:查找的更多相关文章
- leetcode 查找每个元素都出现两次的列表,返回只出现一次的元素
Given an array of integers, every element appears # twice except for one. Find that single one. clas ...
- [LeetCode] Add and Search Word - Data structure design 添加和查找单词-数据结构设计
Design a data structure that supports the following two operations: void addWord(word) bool search(w ...
- Leetcode 35 Search Insert Position 二分查找(二分下标)
基础题之一,是混迹于各种难题的基础,有时会在小公司的大题见到,但更多的是见于选择题... 题意:在一个有序数列中,要插入数target,找出插入的位置. 楼主在这里更新了<二分查找综述>第 ...
- 【题解】【数组】【查找】【Leetcode】Search in Rotated Sorted Array
Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 migh ...
- [LeetCode] #167# Two Sum II : 数组/二分查找/双指针
一. 题目 1. Two Sum II Given an array of integers that is already sorted in ascending order, find two n ...
- leetcode二分查找问题整理
自从做完leetcode上的三道关于二分查找的题后,我觉得它是比链表找环还恶心的题,首先能写出bugfree代码的人就不多,而且可以有各种变形,适合面试的时候不断挑战面试者,一个程序猿写代码解决问题的 ...
- [LeetCode] #1# Two Sum : 数组/哈希表/二分查找/双指针
一. 题目 1. Two SumTotal Accepted: 241484 Total Submissions: 1005339 Difficulty: Easy Given an array of ...
- leetcode 二分查找
https://oj.leetcode.com/problems/search-for-a-range/就是一个二分查找,没事练练手 public class Solution { public in ...
- 【leetcode边做边学】二分查找应用
很多其它请关注我的HEXO博客:http://jasonding1354.github.io/ 简书主页:http://www.jianshu.com/users/2bd9b48f6ea8/lates ...
- [LeetCode] 74 Search a 2D Matrix(二分查找)
二分查找 1.二分查找的时间复杂度分析: 二分查找每次排除掉一半不合适的值,所以对于n个元素的情况来说: 一次二分剩下:n/2 两次:n/4 m次:n/(2^m) 最坏情况是排除到最后一个值之后得到结 ...
随机推荐
- BZOJ3620(kmp)
要点 本题使用\(O(n^2)\)的算法 外层枚举左端点,内层一直kmp到结尾,中间遇到合法的就ans++ 如果是acccca这种数据直接kmp过程顺手判断即可:但是aaa这种数据,j = 2,实际判 ...
- css过渡transition
定义 过渡transition是一个复合属性,包括transition-property.transition-duration.transition-timing-function.transiti ...
- IDEA中如何添加jar包
File -> Project Structure -> Libraries -> + -> jar -> 选择classes
- servlet3
亿级流量架构 http://www.iteye.com/blogs/subjects/as-core servlet3.1对比 http://jinnianshilongnian.iteye.com/ ...
- vue2.0组件的生命周期
beforeCreate(){ console.log(new Date().getTime()) let data = this.text; console.log('组件创立之前') consol ...
- Dev Express Report 学习总结(三)关于子报表Sub-Report的使用
子报表即在一个Report(主报表)中嵌入另一个Report(子报表),从理论上来讲,任何一个Report都可以作为一个子报表,但在实际使用过程中,只有主报表和子报表构成一对多关系时才会使用子报表.使 ...
- grunt 安装使用(一)
grunt 依赖nodejs,所有在使用前确保你安装了nodejs,然后开始执行grunt命令. .安装node nodejs安装教程 安装完成后在命令行,执行命令: node -v 出现版本信息, ...
- 细讲递归(recursion)
首先先对递归进行入门. 递归是以自相似的方式重复项目的过程.在编程语言中,如果程序允许您在同一函数内调用函数,则称其为函数的递归调用. 简而言之,递归就是函数的自身调用.可以看看下面的递归使用: vo ...
- Quartz使用(6) - Quartz项目实战
本片博文将阐述项目工作中使用Quartz的情况,包含项目背景.项目框架.Quartz集群部署等方面,重点讲述如何在实际项目中使用Quartz. 1. 背景 因项目需求,需要定时调用数据下载接口,并将数 ...
- QML 读取本地文件内容
QML 对本地文件的读写 QML 里似乎没有提供直接访问本地文件的模块,但是我们能够自己扩展 QML,给它加上访问本地文件的能力. Qt 官方文档对 QML 是这样介绍的: It defines an ...