Leetcode-Java(二十一)

2018-06-10  本文已影响34人  文哥的学习日记

201. Bitwise AND of Numbers Range

这里的思想是只看m和n两个数,如果m和n前面有几位相同的话,那么他们中间的数和他们的前几位一定也会相同。

class Solution {
    public int rangeBitwiseAnd(int m, int n) {
        if(m==0)
            return 0;
        int moveFactor = 1;
        while(m!=n){
            m >>= 1;
            n >>= 1;
            moveFactor <<= 1;
        }
        return m*moveFactor;
    }
}

202. Happy Number

用一个set保存出现过的数,当出现重复的数的时候,说明不是happy number

class Solution {
    public boolean isHappy(int n) {
        Set<Integer> set = new HashSet<Integer>();
        set.add(n);
        while(true){
            int squaresum = 0;
            while(n > 0){
                squaresum += Math.pow(n%10,2);
                n /= 10;
            }
            if(squaresum == 1)
                return true;
            if(set.contains(squaresum))
                break;
            else
                set.add(squaresum);
            n = squaresum;
        }
        return false;
    }
}

203. Remove Linked List Elements

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode removeElements(ListNode head, int val) {
        ListNode dummy = new ListNode(-1);
        dummy.next = head;
        ListNode p = dummy;
        ListNode q = dummy.next;
        while(q!=null){
            if(q.val == val)
                q = q.next;
            else{
                p.next = q;
                q = q.next;
                p = p.next;
            }
        }
        p.next = null;
        return dummy.next;
    }
}

204. Count Primes

使用一个boolean数组

class Solution {
    public int countPrimes(int n) {
        boolean[] res = new boolean[n];
        int count = 0;
        for(int i=2;i<n;i++){
            if(res[i]==false){
                count ++;
            }
            for(int j = 2;i * j < n;j++){
                res[i * j] = true;
            }
        }
        return count;
    }
}

205. Isomorphic Strings

如果只使用使用一个map,记录下两个string中对应的位置的字母的关系,像egg和add这种是可以准确判断的,但是对于ab和aa这种就会判断错误,所以还需要一个set,保存下第二个字符串中出现过的字符。

class Solution {
    public boolean isIsomorphic(String s, String t) {
        Map<Character,Character> map = new HashMap<Character,Character>();
        Set<Character> set = new HashSet<Character>();
        for(int i =0;i<t.length();i++){
            if(map.containsKey(s.charAt(i))){
                if(map.get(s.charAt(i)) != t.charAt(i))
                    return false;
            }
            else if(set.contains(t.charAt(i))){
                return false;
            }
            map.put(s.charAt(i),t.charAt(i));
            set.add(t.charAt(i));
        }
        return true;
    }
}

206. Reverse Linked List

链表的转置

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode reverseList(ListNode head) {
        if(head==null)
            return null;
        ListNode dummy = new ListNode(-1);
        dummy.next = head;
        ListNode q = dummy.next.next;
        while(q!=null){
            ListNode s = q.next;
            q.next = dummy.next;
            dummy.next = q;
            q = s;
        }
        head.next = null;
        return dummy.next;
    }
}

207. Course Schedule

使用深度优先遍历的算法,构建一个邻接表,并判断图中是否有环

class Solution {
    public boolean canFinish(int numCourses, int[][] prerequisites) {
        List<Integer>[] edges = new ArrayList[numCourses];
        for(int i=0;i<numCourses;i++){
            edges[i] = new ArrayList<Integer>();
        }
        for(int i=0;i<prerequisites.length;i++){
            edges[prerequisites[i][0]].add(prerequisites[i][1]);
        }
        boolean[] visited = new boolean[numCourses];
        for(int i=0;i<numCourses;i++){
            if(!dfs(edges,visited,i))
                return false;
        }
        return true;
    }
    
    public boolean dfs(List<Integer>[] edges,boolean[] visited,int start){
        if(visited[start])
            return false;
        visited[start] = true;
        for(int temp : edges[start]){
            if(!dfs(edges,visited,temp))
                return false;
        }
        visited[start] = false;
        return true;
    }

}

208. Implement Trie (Prefix Tree)

实现字典树,关于字典树的实现,参考我的文章:https://www.jianshu.com/p/f5a9479f304c

class Trie {
    private int size = 26;
    private TrieNode root;
    
    class TrieNode {
        private TrieNode[] son;
        private boolean isEnd;
        private char val;
        
        TrieNode(){
            son = new TrieNode[size];
            isEnd = false;
        }
    }
    
    /** Initialize your data structure here. */
    public Trie() {
        this.root = new TrieNode();
    }
    
    /** Inserts a word into the trie. */
    public void insert(String word) {
        if(word==null || word.length()==0)
             return;
        char[] letters = word.toCharArray();
        TrieNode node = root;
        for(int j=0;j<letters.length;j++){
            int pos = letters[j] - 'a';
            if(node.son[pos]==null){
                node.son[pos] = new TrieNode();
                node.son[pos].val = letters[j];
            }
            node = node.son[pos];
        }
        node.isEnd = true; 
    }
    
    /** Returns if the word is in the trie. */
    public boolean search(String word) {
        if(word==null || word.length()==0)
             return false;
        char[] letters = word.toCharArray();
        TrieNode node = root;
        for(int j=0;j<letters.length;j++){
            int pos = letters[j] - 'a';
            if(node.son[pos]==null)
                return false;
            node = node.son[pos];
        }
        return node.isEnd;
    }
    
    /** Returns if there is any word in the trie that starts with the given prefix. */
    public boolean startsWith(String prefix) {
        if(prefix==null || prefix.length()==0)
             return false;
        char[] letters = prefix.toCharArray();
        TrieNode node = root;
        for(int j=0;j<letters.length;j++){
            int pos = letters[j] - 'a';
            if(node.son[pos]==null)
                return false;
            node = node.son[pos];
        }
        return true;
    }
}

/**
 * Your Trie object will be instantiated and called as such:
 * Trie obj = new Trie();
 * obj.insert(word);
 * boolean param_2 = obj.search(word);
 * boolean param_3 = obj.startsWith(prefix);
 */

209. Minimum Size Subarray Sum

这是我自己的O(n)的解法,维护两个指针,如果数组的和大于:

class Solution {
    public int minSubArrayLen(int s, int[] nums) {
        if(nums==null || nums.length == 0)
            return 0;
        int left = 0;
        int right = 1;
        int n = nums.length;
        int res = 0xffffff;
        int sum = nums[0];
        while(left < n){
            if(sum >= s){
                res = Math.min(right-left,res);
                if(res == 1)
                    return res;
                sum -= nums[left];
                left++;
                
            }
            else{
                right++;
                if(right > n)
                    break;
                sum += nums[right-1];
                
            }
                 
        }
        return res==0xffffff?0:res;
    }
}

210. Course Schedule II

深度优先遍历,首先建立两个数组变量,一个表示该课程是否已经上过,一个表示在当前一轮遍历中是否被访问过,用于判定是否出现了圈。

首先我们建立每门课的一个前置课程的数组,然后从头开始遍历,如果这门课没有前置课程,直接学习,如果有前置课程,那么就往前进行深度优先遍历,直到所有的课程都已经上过。

要时刻判断是否有环出现,有环出现不能全部上完,直接返回null。

class Solution {
    boolean[] discoverd;
    boolean[] visited;
    int[] res;
    int counter = 0;
    
    public int[] findOrder(int numCourses, int[][] prerequisites) {
        discoverd = new boolean[numCourses];
        visited = new boolean[numCourses];
        res = new int[numCourses];
        
        List<Integer>[] preCourses = getPreCourses(numCourses,prerequisites);
        
        for(int i=0;i<numCourses;i++){
            if(!discoverd[i]){
                if(preCourses[i] == null){
                    discoverd[i] = true;
                    res[counter++] = i;
                }
                else{
                    if(findCycle(i,preCourses))
                        return new int[0];
                }
            }
           
        }
        return res;
    }
    
    public List<Integer>[] getPreCourses(int numCourses,int[][] prequery){
        List<Integer>[] list = new ArrayList[numCourses];
        for(int i=0 ; i<prequery.length;i++){
            int pre = prequery[i][1];
            int next = prequery[i][0];
            
            if(list[next] == null)
                list[next] = new ArrayList<Integer>();
            list[next].add(pre);
        }
        return list;
    }
    
    public boolean findCycle(int i,List<Integer>[] preCourses){
        List<Integer> preCourse = preCourses[i];
        visited[i] = true;
        boolean result = false;
        if(preCourse != null){
            for(int course:preCourse){
                if(visited[course] == true){
                    result = true;
                    break;
                }
                else if(discoverd[course]){
                    continue;
                }
                else{
                    if(findCycle(course,preCourses)){
                        result = true;
                        break;
                    }
                }

            }
        }
        
        discoverd[i] = true;
        res[counter++] = i;
        visited[i] = false;
        return result;
    }
}
上一篇下一篇

猜你喜欢

热点阅读