Skip to content

Commit e5f6fdc

Browse files
committed
group anagram,validanagram,NumbersofIsland
1 parent a65e81a commit e5f6fdc

File tree

6 files changed

+364
-0
lines changed

6 files changed

+364
-0
lines changed
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
// Copyright 2016 Baidu Inc. All rights reserved.
2+
3+
package joshua.leetcode.array.unionfind;
4+
5+
import java.util.HashSet;
6+
import java.util.Set;
7+
8+
import joshua.leetcode.solutiontag.UnionFind;
9+
10+
/**
11+
* 200. Number of Islands<br/>
12+
* <p/>
13+
* <a href="https://leetcode.com/problems/number-of-islands/">leetcode link</a>
14+
*
15+
* @author Jiang Yong ([email protected])
16+
*/
17+
public abstract class NumberOfIslands {
18+
19+
/**
20+
* Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.
21+
* <p/>
22+
* Example 1:
23+
* <p/>
24+
* 11110
25+
* 11010
26+
* 11000
27+
* 00000
28+
* Answer: 1
29+
* <p/>
30+
* Example 2:
31+
* <p/>
32+
* 11000
33+
* 11000
34+
* 00100
35+
* 00011
36+
* Answer: 3
37+
*
38+
* @param grid
39+
* @return
40+
*/
41+
public abstract int numIslands(char[][] grid);
42+
43+
@UnionFind
44+
public static class Solution1 extends NumberOfIslands {
45+
46+
@Override
47+
public int numIslands(char[][] grid) {
48+
if (grid == null || grid.length == 0 || grid[0] == null || grid[0].length == 0)
49+
return 0;
50+
int height = grid.length;
51+
int width = grid[0].length;
52+
int[] roots = new int[height * width];
53+
for (int i = 0; i < roots.length; i++) {
54+
int h = i / width;
55+
int j = i % width;
56+
if (grid[h][j] == '1') {
57+
roots[i] = i;
58+
}
59+
}
60+
for (int i = 0; i < roots.length; i++) {
61+
int h = i / width;
62+
int w = i % width;
63+
if (grid[h][w] == '0') continue;
64+
// up
65+
if (h > 0 && grid[h - 1][w] == '1') {
66+
connect(i, i - width, roots);
67+
}
68+
// left
69+
if (w > 0 && grid[h][w - 1] == '1') {
70+
connect(i, i - 1, roots);
71+
}
72+
}
73+
Set<Integer> distinctRoots = new HashSet<Integer>();
74+
for (int i = 0; i < roots.length; i++) {
75+
int h = i / width;
76+
int w = i % width;
77+
if (grid[h][w] == '0') continue;
78+
int topRoot = findParent(roots, i);
79+
distinctRoots.add(topRoot);
80+
}
81+
return distinctRoots.size();
82+
}
83+
84+
private int findParent(int[] roots, int x) {
85+
while (roots[x] != x) x = roots[x];
86+
return x;
87+
}
88+
89+
private void connect(int x, int y, int[] roots) {
90+
int rootX = findParent(roots, x);
91+
int rootY = findParent(roots, y);
92+
if (rootX != rootY)
93+
roots[rootX] = rootY;
94+
}
95+
}
96+
97+
public static class Solution2 extends NumberOfIslands {
98+
99+
@Override
100+
public int numIslands(char[][] grid) {
101+
if (grid == null || grid.length == 0 || grid[0] == null || grid[0].length == 0)
102+
return 0;
103+
int height = grid.length;
104+
int width = grid[0].length;
105+
int count = 0;
106+
for (int i = 0; i < height; i++) {
107+
for (int j = 0; j < width; j++) {
108+
if (grid[i][j] != '0') {
109+
markAsDrown(grid, i , j);
110+
count ++;
111+
}
112+
}
113+
}
114+
return count;
115+
}
116+
117+
private void markAsDrown(char[][] grid, int i, int j) {
118+
if( i < 0 || i > grid.length -1 || j < 0 || j > grid[0].length -1 || grid[i][j] == '0')
119+
return;
120+
grid[i][j] = '0';
121+
markAsDrown(grid, i - 1, j);
122+
markAsDrown(grid, i + 1, j);
123+
markAsDrown(grid, i, j-1);
124+
markAsDrown(grid, i, j+1);
125+
}
126+
}
127+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// Copyright 2016 Baidu Inc. All rights reserved.
2+
3+
package joshua.leetcode.hashtable;
4+
5+
import java.util.ArrayList;
6+
import java.util.Collections;
7+
import java.util.HashMap;
8+
import java.util.LinkedList;
9+
import java.util.List;
10+
import java.util.Map;
11+
import java.util.Set;
12+
import java.util.TreeSet;
13+
14+
/**
15+
* 49. Group Anagrams<br/>
16+
* <a href="https://leetcode.com/problems/anagrams/">leetcode link</a>
17+
*
18+
* @author Jiang Yong ([email protected])
19+
*/
20+
public abstract class GroupAnagrams {
21+
22+
/**
23+
* Given an array of strings, group anagrams together.
24+
* <p/>
25+
* For example, given: ["eat", "tea", "tan", "ate", "nat", "bat"],
26+
* Return:
27+
* <p/>
28+
* [<br/>
29+
* ["ate", "eat","tea"],<br/>
30+
* ["nat","tan"],<br/>
31+
* ["bat"]<br/>
32+
* ]<br/>
33+
* Note:<br/>
34+
* <ul>
35+
* <li>For the return value, each inner list's elements must follow the lexicographic order.</li>
36+
* <li>All inputs will be in lower-case.</li>
37+
* </ul>
38+
*
39+
* @param strs
40+
* @return
41+
*/
42+
public abstract List<List<String>> groupAnagrams(String[] strs);
43+
44+
public static class Solution1 extends GroupAnagrams{
45+
46+
@Override
47+
public List<List<String>> groupAnagrams(String[] strs) {
48+
Map<String, List<String>> anagrams = new HashMap<String, List<String>>();
49+
for (String str : strs) {
50+
int[] flags = new int[26];
51+
for(char ch : str.toCharArray()) {
52+
flags[ch - 'a']++;
53+
}
54+
StringBuilder stringBuilder = new StringBuilder();
55+
for (int flag : flags) {
56+
stringBuilder.append(flag);
57+
}
58+
String key = stringBuilder.toString();
59+
if (!anagrams.containsKey(key)) {
60+
List<String> group = new LinkedList<String>();
61+
group.add(str);
62+
anagrams.put(key, group);
63+
} else {
64+
List<String> group = anagrams.get(key);
65+
group.add(str);
66+
}
67+
}
68+
List<List<String>> result = new ArrayList<List<String>>();
69+
for(List<String> group : anagrams.values()) {
70+
Collections.sort(group);
71+
result.add(group);
72+
}
73+
return result;
74+
}
75+
}
76+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Copyright 2016 Baidu Inc. All rights reserved.
2+
3+
package joshua.leetcode.hashtable;
4+
5+
/**
6+
* 242. Valid Anagram<br/>
7+
* <p/>
8+
* <a href="https://leetcode.com/problems/valid-anagram/">leetcode link</a>
9+
*
10+
* @author Jiang Yong ([email protected])
11+
*/
12+
public abstract class ValidAnagram {
13+
14+
/**
15+
* Given two strings s and t, write a function to determine if t is an anagram of s.
16+
* <p/>
17+
* For example,
18+
* s = "anagram", t = "nagaram", return true.
19+
* s = "rat", t = "car", return false.
20+
* <p/>
21+
* Note:<br/>
22+
* You may assume the string contains only lowercase alphabets.
23+
* <p/>
24+
* Follow up:<br/>
25+
* What if the inputs contain unicode characters? How would you adapt your solution to such case?
26+
*
27+
* @param s
28+
* @param t
29+
* @return
30+
*/
31+
public abstract boolean isAnagram(String s, String t);
32+
33+
34+
public static class Solution1 extends ValidAnagram {
35+
36+
@Override
37+
public boolean isAnagram(String s, String t) {
38+
int[] flags = new int[26];
39+
for(char ch : s.toCharArray()) flags[ch - 'a'] ++;
40+
for(char ch : t.toCharArray()) flags[ch - 'a'] --;
41+
for(int flag : flags)
42+
{
43+
if (flag != 0) return false;
44+
}
45+
return true;
46+
}
47+
}
48+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package joshua.leetcode.array.unionfind;
2+
3+
import static org.junit.Assert.assertEquals;
4+
5+
import java.util.Map;
6+
7+
import org.junit.Before;
8+
import org.junit.Test;
9+
10+
import com.google.common.collect.Maps;
11+
12+
public class NumberOfIslandsTest {
13+
14+
private Map<char[][], Integer> cases = Maps.newHashMap();
15+
16+
@Before
17+
public void setUp() {
18+
char[][] islands = new char[][]{
19+
{'1' ,'1','1'},
20+
{'0' ,'1','0'},
21+
{'1' ,'1','1'}
22+
};
23+
cases.put(islands, 1);
24+
}
25+
26+
@Test
27+
public void testSolution2() {
28+
NumberOfIslands solution = new NumberOfIslands.Solution2();
29+
for(char[][] islands : cases.keySet()) {
30+
int num = solution.numIslands(islands);
31+
assertEquals((int)cases.get(islands), num);
32+
}
33+
}
34+
35+
@Test
36+
public void testSolution1() {
37+
NumberOfIslands solution = new NumberOfIslands.Solution1();
38+
for(char[][] islands : cases.keySet()) {
39+
int num = solution.numIslands(islands);
40+
assertEquals((int)cases.get(islands), num);
41+
}
42+
}
43+
44+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package joshua.leetcode.hashtable;
2+
3+
import static org.junit.Assert.*;
4+
5+
import java.util.ArrayList;
6+
import java.util.List;
7+
import java.util.Map;
8+
9+
import org.junit.Before;
10+
import org.junit.Test;
11+
12+
import com.google.common.collect.Lists;
13+
import com.google.common.collect.Maps;
14+
15+
public class GroupAnagramsTest {
16+
17+
private Map<String[], List<List<String>>> cases = Maps.newHashMap();
18+
19+
@Before
20+
public void setUp() {
21+
String[] strings = new String[]{"eat", "tea", "tan", "ate", "nat", "bat"};
22+
List<List<String>> results = new ArrayList<List<String>>();
23+
results.add(Lists.newArrayList("ate", "eat","tea"));
24+
results.add(Lists.newArrayList("nat","tan"));
25+
results.add(Lists.newArrayList("bat"));
26+
cases.put(strings, results);
27+
}
28+
29+
@Test
30+
public void testSolution1() {
31+
GroupAnagrams solution = new GroupAnagrams.Solution1();
32+
for(String[] testcase: cases.keySet()) {
33+
List<List<String>> result = solution.groupAnagrams(testcase);
34+
for(List<String> res :result) {
35+
System.out.println(res);
36+
}
37+
}
38+
}
39+
40+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package joshua.leetcode.hashtable;
2+
3+
import static org.junit.Assert.*;
4+
5+
import java.util.Map;
6+
7+
import org.junit.Before;
8+
import org.junit.Test;
9+
10+
import com.google.common.collect.Maps;
11+
12+
public class ValidAnagramTest {
13+
14+
private Map<String, String> postiveCases = Maps.newHashMap();
15+
private Map<String, String> negativeCases = Maps.newHashMap();
16+
17+
@Before
18+
public void setUp() {
19+
postiveCases.put("nagaram", "anagram");
20+
}
21+
22+
@Test
23+
public void testSolution1() {
24+
ValidAnagram solution = new ValidAnagram.Solution1();
25+
for(String key : postiveCases.keySet()) {
26+
assertTrue(solution.isAnagram(key, postiveCases.get(key)));
27+
}
28+
}
29+
}

0 commit comments

Comments
 (0)