Skip to content

Commit e7d6889

Browse files
committed
Minimum Window substring
1 parent d43ca12 commit e7d6889

23 files changed

+898
-200
lines changed

src/main/java/joshua/algorithm/math/FirstNPrime.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55

66
/**
77
* 输出前 N 个 质数,质数除1外只能被自身整除。
8-
*
9-
*
8+
* <p/>
9+
* <p/>
1010
* Created by joshu on 2016/5/25.
1111
*/
1212
public abstract class FirstNPrime {
@@ -15,8 +15,8 @@ public abstract class FirstNPrime {
1515

1616
/**
1717
* 类似 {@link joshua.leetcode.math.CountPrime} 的 方法。
18-
* 对每个数m,已知 小于m的所有的质数[2,..k,..],则对于小于m的开方的所有质数,如果都不能整除m,则m也是素数
19-
* 否则继续对m+1判断。
18+
* 对每个数m,已知 小于m的所有的质数[2,..k,..],则对于小于m的开方的所有质数,如果都不能整除m,则m也是素数
19+
* 否则继续对m+1判断。
2020
*/
2121
public static class Solution1 extends FirstNPrime {
2222

@@ -27,12 +27,13 @@ public List<Long> getFirstNPrime(int n) {
2727
int count = 1;
2828
long currentNum = 3;
2929
while (count < n) {
30+
// k means the idx of the founded prime list
3031
int k = 0;
3132
// get the next prime, count == primes.size()
3233
while (k < count && primes.get(k) * primes.get(k) <= currentNum) {
3334
if (currentNum % primes.get(k) == 0) {
3435
k = 0;
35-
currentNum +=1;
36+
currentNum += 1;
3637
} else {
3738
k++;
3839
}

src/main/java/joshua/leetcode/array/DualSum.java

Lines changed: 0 additions & 89 deletions
This file was deleted.

src/main/java/joshua/leetcode/array/TernarySum.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import java.util.ArrayList;
44
import java.util.Arrays;
5-
import java.util.HashSet;
65
import java.util.List;
76

87
/**
@@ -37,7 +36,7 @@ Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤
3736
* A derivation of DualSum problem.
3837
* Time Complexity: o(n<sup>2</sup>)
3938
*
40-
* @see {@link DualSum}
39+
* @see {@link joshua.leetcode.array.twopointers.TwoSum}
4140
* @author joy
4241
*
4342
*/
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
// Copyright 2016 Baidu Inc. All rights reserved.
2+
3+
package joshua.leetcode.array.twopointers;
4+
5+
import java.util.HashMap;
6+
7+
/**
8+
* 76. Minimum Window Substring<br/>
9+
* <p/>
10+
* <a href = "https://leetcode.com/problems/minimum-window-substring/">leetcode link</a>
11+
*
12+
* @author Jiang Yong ([email protected])
13+
*/
14+
public abstract class MinimumWindowSubstring {
15+
16+
/**
17+
* Given a string S and a string T,
18+
* find the minimum window in S which will contain all the characters in T in complexity O(n).
19+
* <p/>
20+
* For example,
21+
* S = "ADOBECODEBANC"
22+
* T = "ABC"
23+
* Minimum window is "BANC".
24+
* <p/>
25+
* Note:
26+
* If there is no such window in S that covers all characters in T, return the empty string "".
27+
* <p/>
28+
* If there are multiple such windows, you are guaranteed that there will always be only one unique minimum window in S.
29+
*/
30+
public abstract String minWindow(String s, String t);
31+
32+
/**
33+
* 这一题类似于:给红绿蓝三种颜色,和一串珠子,要求找出最短的连续子串包含这三种颜色。
34+
*
35+
* 这一题要求O(n)的时间复杂度,因此考虑Two Pointers。
36+
* left pointer 指向子串的头,right pointer 指向子串的尾。
37+
*
38+
* 这里需要记录若干个变量:
39+
* 1) 当前某个字符是不是包含在T中,用hash map
40+
* 2) 当前是不是找到了所有T中的字符, 用一个计数变量;
41+
* 3) 当找到了包含所有T中字符的子串之后,需要判断是不是最短子串,因此需要保存最短子串的长度;
42+
* 4) 对于当前最短子串,通过substring[leftpointer, rightpointer]得到子串
43+
* 5) 什么时候移动 left pointer?
44+
* 当移动right pointer 发现有一个T中字符的出现次数大于1时,说明有重复了,则需要将
45+
* left pointer移动到下一个只出现了一次的字符的位置
46+
* 或者已经找到了某个符合条件的子串,可以移动left pointer到下一个属于T的字符
47+
*
48+
*/
49+
public static class Solution1 extends MinimumWindowSubstring {
50+
51+
@Override
52+
public String minWindow(String s, String t) {
53+
int minimumLength = Integer.MAX_VALUE;
54+
String minimumStr = "";
55+
// flags means how many characters there have met the requirement, with same occurrence as t.
56+
int flag = 0;
57+
int distinctChars = 0;
58+
HashMap<Character, Integer> countRecorderS = new HashMap<Character, Integer>();
59+
HashMap<Character, Integer> countRecorderT = new HashMap<Character, Integer>();
60+
for(Character ch : t.toCharArray()) {
61+
if (countRecorderT.containsKey(ch)) {
62+
countRecorderT.put(ch, countRecorderT.get(ch) + 1);
63+
} else {
64+
countRecorderT.put(ch, 1);
65+
distinctChars ++;
66+
}
67+
countRecorderS.put(ch, 0);
68+
}
69+
int leftPointer = 0 , rightPointer = 0;
70+
while(rightPointer < s.length()) {
71+
char ch = s.charAt(rightPointer);
72+
if (! countRecorderS.containsKey(ch)) {
73+
rightPointer ++;
74+
} else {
75+
countRecorderS.put(ch, countRecorderS.get(ch) + 1);
76+
if (countRecorderS.get(ch).equals(countRecorderT.get(ch))) {
77+
flag ++;
78+
}
79+
// check and move left pointer
80+
while (leftPointer <= rightPointer) {
81+
if (!countRecorderS.containsKey(s.charAt(leftPointer))) {
82+
leftPointer ++;
83+
} else if (countRecorderS.get(s.charAt(leftPointer)) > countRecorderT.get(s.charAt(leftPointer))) {
84+
countRecorderS.put(s.charAt(leftPointer), countRecorderS.get(s.charAt(leftPointer)) -1);
85+
leftPointer ++;
86+
} else {
87+
break;
88+
}
89+
}
90+
// check if got the valid substring
91+
if (distinctChars == flag) {
92+
if (rightPointer - leftPointer + 1 < minimumLength) {
93+
minimumLength = rightPointer - leftPointer + 1;
94+
minimumStr = s.substring(leftPointer, rightPointer+1);
95+
}
96+
//move left pointer one step to right direction.
97+
countRecorderS.put(s.charAt(leftPointer), countRecorderS.get(s.charAt(leftPointer)) -1);
98+
flag --;
99+
leftPointer ++;
100+
}
101+
rightPointer ++;
102+
}
103+
}
104+
return minimumStr;
105+
}
106+
}
107+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package joshua.leetcode.array.twopointers;
2+
3+
import java.util.Arrays;
4+
import java.util.HashMap;
5+
6+
import joshua.leetcode.solutiontag.TwoPointers;
7+
8+
9+
/**
10+
* Two Sum.</br>
11+
* <B>tags:</B> Array, HashTable.
12+
*
13+
* @author Joshua.Jiang
14+
* @see <a href="https://oj.leetcode.com/problems/two-sum/">https://oj.leetcode.com/problems/two-sum/</a></br>
15+
*/
16+
public abstract class TwoSum {
17+
18+
/**
19+
* Given an array of integers, find two numbers such that they add up to a specific target number.
20+
* <p/>
21+
* The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2.
22+
* <p/>
23+
* Please note that your returned answers (both index1 and index2) are not zero-based.
24+
* <p/>
25+
* You may assume that each input would have exactly one solution.
26+
* <p/>
27+
* Input: numbers={2, 7, 11, 15}, target=9
28+
* Output: index1=1, index2=2
29+
*
30+
* @param numbers
31+
* @param target
32+
* @return
33+
*/
34+
public abstract int[] twoSum(int[] numbers, int target);
35+
36+
/**
37+
* use HashMap to find the element.
38+
*
39+
* @author joy
40+
*/
41+
static class Solution1 extends TwoSum {
42+
43+
@Override
44+
public int[] twoSum(int[] numbers, int target) {
45+
HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
46+
int i = 0;
47+
for (int num : numbers) {
48+
map.put(num, i++);
49+
}
50+
for (i = 0; i < numbers.length; i++) {
51+
Integer index = map.get(target - numbers[i]);
52+
if (index != null && index > i)
53+
return new int[]{i + 1, index + 1};
54+
}
55+
return null;
56+
}
57+
}
58+
59+
/**
60+
* 1)sort the array firstly;
61+
* 2)set two pointers, one at the head, one at the tail;
62+
* 3)move the tail or head pointer if the sum is bigger or smaller than the target value;
63+
* 4)function exit if the two pointers meet or we find the pair with correct sum;
64+
*
65+
* @author joy
66+
*/
67+
@TwoPointers
68+
static class Solution2 extends TwoSum {
69+
70+
@Override
71+
public int[] twoSum(int[] numbers, int target) {
72+
Arrays.sort(numbers);
73+
int i = 0, j = numbers.length - 1;
74+
while (i < j) {
75+
int sum = numbers[i] + numbers[j];
76+
if (sum == target)
77+
return new int[]{i + 1, j + 1};
78+
else if (sum < target)
79+
i++;
80+
else
81+
j--;
82+
}
83+
return null;
84+
}
85+
86+
}
87+
}

0 commit comments

Comments
 (0)