lintcode做题总结, Oct 05

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;
    }
}


3. Candy 高rating的人要比邻居分数高。只需要先从左到右高历遍数组确保满足条件,然后再从右向左历遍确保满足条件

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));
        }
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值