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:

  1. Only one letter can be changed at a time
  2. 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 (a1a2, … , 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:查找的更多相关文章

  1. leetcode 查找每个元素都出现两次的列表,返回只出现一次的元素

    Given an array of integers, every element appears # twice except for one. Find that single one. clas ...

  2. [LeetCode] Add and Search Word - Data structure design 添加和查找单词-数据结构设计

    Design a data structure that supports the following two operations: void addWord(word) bool search(w ...

  3. Leetcode 35 Search Insert Position 二分查找(二分下标)

    基础题之一,是混迹于各种难题的基础,有时会在小公司的大题见到,但更多的是见于选择题... 题意:在一个有序数列中,要插入数target,找出插入的位置. 楼主在这里更新了<二分查找综述>第 ...

  4. 【题解】【数组】【查找】【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 ...

  5. [LeetCode] #167# Two Sum II : 数组/二分查找/双指针

    一. 题目 1. Two Sum II Given an array of integers that is already sorted in ascending order, find two n ...

  6. leetcode二分查找问题整理

    自从做完leetcode上的三道关于二分查找的题后,我觉得它是比链表找环还恶心的题,首先能写出bugfree代码的人就不多,而且可以有各种变形,适合面试的时候不断挑战面试者,一个程序猿写代码解决问题的 ...

  7. [LeetCode] #1# Two Sum : 数组/哈希表/二分查找/双指针

    一. 题目 1. Two SumTotal Accepted: 241484 Total Submissions: 1005339 Difficulty: Easy Given an array of ...

  8. leetcode 二分查找

    https://oj.leetcode.com/problems/search-for-a-range/就是一个二分查找,没事练练手 public class Solution { public in ...

  9. 【leetcode边做边学】二分查找应用

    很多其它请关注我的HEXO博客:http://jasonding1354.github.io/ 简书主页:http://www.jianshu.com/users/2bd9b48f6ea8/lates ...

  10. [LeetCode] 74 Search a 2D Matrix(二分查找)

    二分查找 1.二分查找的时间复杂度分析: 二分查找每次排除掉一半不合适的值,所以对于n个元素的情况来说: 一次二分剩下:n/2 两次:n/4 m次:n/(2^m) 最坏情况是排除到最后一个值之后得到结 ...

随机推荐

  1. CF D. Fair(思维+DFS)

    http://codeforces.com/contest/987/problem/D 题目大概: 给出一个n个城镇m条边的图,给出每个城镇拥有的特产(可能多个城镇有相同特产).有k种不同特产. 要求 ...

  2. Observable Flowable Test

    package com.test.rxjava; import java.time.Duration; import java.time.Instant; import java.util.Linke ...

  3. JavaScript中使用ActiveXObject操作本地文件夹的方法

    转载地址    http://www.jb51.net/article/48538.htm 在Windows平台上, js可以调用很多Windows提供的ActivexObject,本文就使用js来实 ...

  4. Redis未授权访问攻击过程与防范

    一.Redis未授权访问攻击过程 攻击主机:kali 目标主机:centos6.8(10.104.11.178) Redis版本:2.8 攻击条件:默认配置,未进行认证 攻击步骤详解: 1.Kali攻 ...

  5. 07-----nodejs 中 npm的使用

    npm是什么? 简单的说,npm就是JavaScript的包管理工具.类似Java语法中的maven,gradle,python中的pip. 安装 傻瓜式的安装. 第一步:打开https://node ...

  6. 《我在谷歌大脑见习机器学习的一年:Node.js创始人的尝试笔记》阅读笔记

    文章来源:https://www.toutiao.com/i6539751003690893828/?tt_from=weixin_moments&utm_campaign=client_sh ...

  7. [转]JS跨域总结

    本文转自:http://www.cnblogs.com/qixuejia/archive/2012/08/29/2662220.html javascript跨域有两种情况: 1.基于同一父域的子域之 ...

  8. Host 'XXX' is not allowed to connect to this MySQL server解决方案

    如何允许远程连接mysql数据库呢,操作如下: 首先登录账号 mysql -uroot -p 使用mysql用户 use mysql 如果报此类错:ERROR 1820 (HY000): You mu ...

  9. OpenStack Weekly Rank 2015.08.03

    Module Reviews Drafted Blueprints Completed Blueprints Filed Bugs Resolved Bugs Cinder 7 1 1 7 11 Sw ...

  10. pat1101. Quick Sort (25)

    1101. Quick Sort (25) 时间限制 200 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CAO, Peng There is a ...