1. Word Ladder 这道题的方法是将word放入队列,然后依次提取然后对于每一个字符进行从a到z的变换。如果等于end则返回,如果等于字典set里的word,则放入map和队列,map里存放字符和对应的距离。
public class Solution {
public int ladderLength(String beginWord, String endWord, Set<String> wordList) {
if (wordList == null || wordList.size() == 0 || beginWord.equals(endWord)) {
return 0;
}
if (beginWord.length() == 1){
return 2;
}
Queue<String> queue = new LinkedList<String>();
HashMap<String, Integer> map = new HashMap<String, Integer>();
queue.add(beginWord);
map.put(beginWord, 1);
while (queue.size() != 0){
String top = queue.poll();
for (int i = 0; i < top.length(); i++){
for (char j = 'a'; j <= 'z'; j++){
if (top.charAt(i) == j){
continue;
}
StringBuilder sb = new StringBuilder(top);
sb.setCharAt(i, j);
if (sb.toString().equals(endWord)){
return map.get(top) + 1;
}
if (wordList.contains(sb.toString()) && !map.containsKey(sb.toString())){
queue.add(sb.toString());
map.put(sb.toString(), map.get(top) + 1);
wordList.remove(sb.toString());
}
}
}
}
return 0;
}
}
2. Word Ladder ii
class WordNode{
String word;
int numSteps;
WordNode pre;
public WordNode(String word, int numSteps, WordNode pre){
this.word = word;
this.numSteps = numSteps;
this.pre = pre;
}
}
public class Solution {
public List<List<String>> findLadders(String start, String end, Set<String> dict) {
List<List<String>> result = new ArrayList<List<String>>();
LinkedList<WordNode> queue = new LinkedList<WordNode>();
queue.add(new WordNode(start, 1, null));
dict.add(end);
int minStep = 0;
HashSet<String> visited = new HashSet<String>();
HashSet<String> unvisited = new HashSet<String>();
unvisited.addAll(dict);
int preNumSteps = 0;
while(!queue.isEmpty()){
WordNode top = queue.remove();
String word = top.word;
int currNumSteps = top.numSteps;
if(word.equals(end)){
if(minStep == 0){
minStep = top.numSteps;
}
if(top.numSteps == minStep && minStep !=0){
//nothing
ArrayList<String> t = new ArrayList<String>();
t.add(top.word);
while(top.pre !=null){
t.add(0, top.pre.word);
top = top.pre;
}
result.add(t);
continue;
}
}
if(preNumSteps < currNumSteps){
unvisited.removeAll(visited);
}
preNumSteps = currNumSteps;
char[] arr = word.toCharArray();
for(int i=0; i<arr.length; i++){
for(char c='a'; c<='z'; c++){
char temp = arr[i];
if(arr[i]!=c){
arr[i]=c;
}
String newWord = new String(arr);
if(unvisited.contains(newWord)){
queue.add(new WordNode(newWord, top.numSteps+1, top));
visited.add(newWord);
}
arr[i]=temp;
}
}
}
return result;
}
}
public class Solution {
public int candy(int[] ratings) {
if (ratings == null || ratings.length == 0){
return 0;
}
int[] candy = new int[ratings.length];
candy[0] = 1;
for (int i = 1; i < ratings.length; i++){
if (ratings[i] > ratings[i-1]){
candy[i] = candy[i-1] + 1;
} else {
candy[i] = 1;
}
}
for (int i = ratings.length - 2; i >= 0; i--){
if (ratings[i] > ratings[i+1]){
if (candy[i] <= candy[i+1])
candy[i] = candy[i+1] + 1;
}
}
int num = 0;
for (int i = 0; i < ratings.length; i++){
num = num + candy[i];
}
return num;
}
}
4. Insert Interval 这道题的思路是历遍原来的元素,如果没有和新的有重叠就添加到新的list,如果有则更新newele。
/**
* Definition for an interval.
* public class Interval {
* int start;
* int end;
* Interval() { start = 0; end = 0; }
* Interval(int s, int e) { start = s; end = e; }
* }
*/
public class Solution {
public List<Interval> insert(List<Interval> intervals, Interval newInterval) {
if (intervals == null || newInterval == null){
return intervals;
}
List<Interval> res = new ArrayList<Interval>();
//ask recuriter if necessary
//Collections.sort(intervals, new IntervalCompare());
for(Interval interval: intervals){
if(interval.end < newInterval.start){
res.add(interval);
}else if(interval.start > newInterval.end){
res.add(newInterval);
newInterval = interval;
}else if(interval.end >= newInterval.start || interval.start <= newInterval.end){
newInterval = new Interval(Math.min(interval.start, newInterval.start), Math.max(newInterval.end, interval.end));
}
}
res.add(newInterval);
return res;
}
class IntervalCompare implements Comparator<Interval>{
public int compare(Interval i1, Interval i2){
return i1.start - i2.start;
}
}
}
5. Distinct Subsequences 这道题是求两个字符串的相同子串个数。用的DP
public class Solution {
public int numDistinct(String s, String t) {
int[] res = new int[t.length()];
for (int i = 0; i < s.length(); i++){
for (int j = t.length() - 1; j >= 0; j--){
if (s.charAt(i) == t.charAt(j)) {
res[j] += j==0?1:res[j-1];
}
}
}
return res[t.length()-1];
}
}
6. Regular Expression Matching 这道题逻辑是递归,首先判断如果为空,然后判断如果剩一个的情况,然后考虑*的情况
public class Solution {
private boolean check(String s, String p, int i, int j){
if (p.length() == 0)
return s.length() == 0;
// length == 1 is the case that is easy to forget.
// as p is subtracted 2 each time, so if original
// p is odd, then finally it will face the length 1
if (p.length() == 1)
return (s.length() == 1) && (p.charAt(0) == s.charAt(0) || p.charAt(0) == '.');
// next char is not '*': must match current character
if (p.charAt(1) != '*') {
if (s.length() == 0)
return false;
else
return (s.charAt(0) == p.charAt(0) || p.charAt(0) == '.')
&& isMatch(s.substring(1), p.substring(1));
}else{
// next char is *
//"while" is used to match "baaaa" with "ba*"
while (s.length() > 0 && (p.charAt(0) == s.charAt(0) || p.charAt(0) == '.')) {
if (isMatch(s, p.substring(2)))
return true;
s = s.substring(1);
}
//this means *==0,ignore the current char.
return isMatch(s, p.substring(2));
}
}
}