From 5c467d56e5710dd30e0d00cc2d08e21a4437118f Mon Sep 17 00:00:00 2001 From: liu13 <1099976891@qq.com> Date: Tue, 8 Jan 2019 15:22:56 +0800 Subject: [PATCH] 20190108 --- code/lc207.java | 92 +++++++++++++++++++++++++++++++++++++++++++++++++ code/lc208.java | 61 ++++++++++++++++++++++++++++++++ code/lc221.java | 36 +++++++++++++++++++ 3 files changed, 189 insertions(+) create mode 100644 code/lc207.java create mode 100644 code/lc208.java create mode 100644 code/lc221.java diff --git a/code/lc207.java b/code/lc207.java new file mode 100644 index 0000000..896259b --- /dev/null +++ b/code/lc207.java @@ -0,0 +1,92 @@ +package code; + +import java.util.*; + +/* + * 207. Course Schedule + * 题意:课程是否能够完成 + * 难度:Medium + * 分类:Depth-first Search, Breadth-first Search, Graph, Topology Sort + * 思路:两种方法,一种BFS拓扑排序,另一种DFS找是否有环 + * Tips:很经典的题,拓扑排序,判断图是否有环的DFS + */ +public class lc207 { + public static void main(String[] args) { + int[][] prerequisites = {{1,0},{0,1}}; + //System.out.println(canFinish(2, prerequisites)); + System.out.println(canFinish2(2, prerequisites)); + } + public static boolean canFinish(int numCourses, int[][] prerequisites) { + int[] indegree = new int[numCourses]; + int[][] graph = new int[numCourses][numCourses]; + for (int i = 0; i < prerequisites.length ; i++) { + int node1 = prerequisites[i][0]; + int node2 = prerequisites[i][1]; + graph[node2][node1] = 1; + indegree[node1]++; //存下入度,入度为0时,表示该课程可以修 + } + Stack st = new Stack(); + int count = 0; + for (int i = 0; i < numCourses ; i++) { + if(indegree[i]==0) { + st.add(i); + count++; + } + } + while(!st.isEmpty()){ + int node = st.pop(); + for (int i = 0; i < numCourses ; i++) { + if(graph[node][i]==1) { + indegree[i]--; + if(indegree[i]==0){ + st.add(i); + count++; + } + } + } + } + return count==numCourses; //可以修的课程==课程数 + } + + public static boolean canFinish2(int numCourses, int[][] prerequisites) { + HashMap> graph = new HashMap<>(); + // 转换成连接表 + for (int i = 0; i < prerequisites.length ; i++) { + int node1 = prerequisites[i][0]; + int node2 = prerequisites[i][1]; + if(graph.containsKey(node1)){ + graph.get(node1).add(node2); + }else{ + LinkedList l = new LinkedList<>(); + l.add(node2); + graph.put(node1, l); + } + } + + Set visited = new HashSet(); //记录没有环的节点 + for (int i = 0; i < numCourses ; i++) { + Set onpath = new HashSet(); //路径上的节点,要声明在里边,换节课后就清空了 + if(hascycle(i,graph,onpath,visited))//有环 + return false; + } + return true; + } + public static boolean hascycle(int course, HashMap graph, Set onpath, Set visited){ + if( visited.contains(course)) //如果该节点之前判断过了没有环 + return false; + if( onpath.contains(course)) + return true; + onpath.add(course); //没有回溯了,自顶向下的,不用remove + LinkedList nodes = (LinkedList)graph.get(course); + if(nodes==null) + return false; + for (int i = 0; i < nodes.size() ; i++) { + if(!hascycle(nodes.get(i), graph, onpath, visited)) + visited.add(nodes.get(i)); + else + return true; + } + onpath.remove((Integer)course); + return false; + } +} diff --git a/code/lc208.java b/code/lc208.java new file mode 100644 index 0000000..5f54b76 --- /dev/null +++ b/code/lc208.java @@ -0,0 +1,61 @@ +package code; +/* + * 208. Implement Trie (Prefix Tree) + * 题意:字典树 + * 难度:Medium + * 分类:Design, Trie + * 思路:字典树是一个数据结构,这个数据结构里包含很多TrieNode,每个TireNode都用一个长度为26的TrieNode[]数组表示该字符的下一个字符对象 + * Tips: + */ +public class lc208 { + class TrieNode { + public char val; + public boolean isWord; + public TrieNode[] children = new TrieNode[26]; + public TrieNode() {} + TrieNode(char c){ + TrieNode node = new TrieNode(); + node.val = c; + } + } + + public class Trie { + private TrieNode root; + public Trie() { + root = new TrieNode(); + root.val = ' '; + } + + public void insert(String word) { + TrieNode ws = root; + for(int i = 0; i < word.length(); i++){ + char c = word.charAt(i); + if(ws.children[c - 'a'] == null){ + ws.children[c - 'a'] = new TrieNode(c); + } + ws = ws.children[c - 'a']; + } + ws.isWord = true; + } + + public boolean search(String word) { + TrieNode ws = root; + for(int i = 0; i < word.length(); i++){ + char c = word.charAt(i); + if(ws.children[c - 'a'] == null) return false; + ws = ws.children[c - 'a']; + } + return ws.isWord; + } + + public boolean startsWith(String prefix) { + TrieNode ws = root; + for(int i = 0; i < prefix.length(); i++){ + char c = prefix.charAt(i); + if(ws.children[c - 'a'] == null) return false; + ws = ws.children[c - 'a']; + } + return true; + } + } +} diff --git a/code/lc221.java b/code/lc221.java new file mode 100644 index 0000000..6f2b289 --- /dev/null +++ b/code/lc221.java @@ -0,0 +1,36 @@ +package code; +/* + * 221. Maximal Square + * 题意:0,1数组中最大正方形 + * 难度:Medium + * 分类:Dynamic Programming + * 思路:三个正方形+上右下角位置,可以组成一个新的正方形 + * Tips:和lc85作比较 + */ +public class lc221 { + public static void main(String[] args) { + char[][] matrix = {{'1','0','1','0','0'},{'1','0','1','1','1'},{'1','1','1','1','1'},{'1','0','0','1','0'}}; + System.out.println(maximalSquare(matrix)); + } + public static int maximalSquare(char[][] matrix) { + if(matrix.length==0) + return 0; + int[][] dp = new int[matrix.length][matrix[0].length]; + int max = 0; + for (int i = 0; i < matrix.length ; i++) { + for (int j = 0; j < matrix[0].length ; j++) { + if(i==0 || j==0) { + dp[i][j] = matrix[i][j]-'0'; + max = Math.max(dp[i][j],max); + } + else{ + if(matrix[i][j]=='1') { + dp[i][j] = Math.min(Math.min(dp[i - 1][j], dp[i][j - 1]), dp[i - 1][j - 1]) + 1; //dp[i][j] 最大正方形边长 + max = Math.max(dp[i][j], max); + } + } + } + } + return max*max; + } +} -- GitLab