1.1 introduction
pros: add, delete, find O(1) time
cons: much storage O(n) space
key value -> int num(in hash function) -> num % n as index
using array, list, resize
When the data is 90% full in the table or more, the efficience begins to drop.
avoid conflict: Linked List in Arrays
if data/size.array() || length.LinkedList > 5:
resize: 2 times size of the array
HashSet & HashMap
1.2 scenarios not suitable for hash tables
- find the ith elements from a data set [array]
- data are sorted(find max/min [heap], find a element greater than a given number [BST])
- hash table
find strings with a prefix
1.3 HashMap
replaced by array
- If the number of keys is fixed and not large, use the array.
- Array’s find function is quicker than hash table.
create
1
2Map<key type, value type> map = new HashMap<>();
|| HashMap<key type, value type> map = new HashMap<>();
PS: about
https://blog.csdn.net/llkoio/article/details/78888721
functions
- map.put(key, value)
add value - map.get(key)
find value - map.getOrDefault(key, defaultNum)
add value from a data set - map.containsKey(key)
find if key exists in map - map.remove(key)
1.4 practice
LC242 valid anagram
possible solution1
1 |
Arrays.sort(array) // sort the array in ascii |
O(nlogn) time
hash table/array
int[] counts = new int[26];
LC49 Group Anagrams
like “dictionary” Map<String, List
LC380 Insert delete GetRandom O(1)
- insert delete: hash table
- get random: array O(1), linkedlist O(n)
- Random type
1
2Random random = new Random();
random.nextInt(int n); //create a random integer from [0,n)
Solution
1 |
HashMap<Integer, Integer> numToLocation; |
first integer -> value, second integer -> index
2 String(two pointers)
2.1 introduction
Think about how and when to move the 2 pointers.
2.2 practice
LC 567 Permutation in String
- brute force
all permutations of s1
each ? substring of s2 - optimization
using 2 pointers to get a s1-length substring of s2
hash table anagram s1, sub_s2(left++,right–)
O(n) time, O(1) space
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21int[] counts = new int[26];
if (s1.length()<s2.length())
{
//Begin with first window
for (int i = 0; i < s1.length(); i++)
{
counts[s1.chatAt(i)-'a']++;
counts[s2.charAt(i)-'a']--;
}
//determine whether it's an anagram
if (areAllZero(counts)) return true;
//滑动窗口,右指针从s1.length()开始,左指针为右-s1.length()
for (int i = s1.length(); i<s2.length(); i++)
{
//right pointer char--,left pointer char++
counts[s2.charAt(i)-'a']--;
counts[s2.charAt(i)-s1.length()-'a']++;
if (areAllZero(counts)) return true;
}
return false;
}
LC 438 Find All Anagrams in a String
- As above.
- Use a list to record the indices.
LC 3 Longest Substring without Repeating
- if key’s value > 1, it’s repeating
- determine: how and when do the pointers move
right: include more character (not repeated)
left: exclude some character (repeated)
right begins from 0, left begins from -1
if the subject doesn’t say the letters are lowercases, use ASCII and the array’s length should be [256].
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15int[] counts = new int[256];
int longest = s.length() > 0 ? 1:0;
for (int i=0, j=-1; i<s.length(); i++)
{
counts[s.charAt(i)]++;
//make it without repeating
while (GreaterThan1(counts))
{
j++;
counts[s.charAt(j)]--;
}
//2 situations: not longer or longer
longest = Math.max(i-j, longest);
}
return longest; - optimization: replace GreaterThan1() with a 2-time-exist index
it has to scan 256’s room every time use GreaterThan1()
1
2
3
4
5
6
7
8
9
10
11int countDup = 0;
...
if (counts[s.charAt(i)] == 2) countDup++;
while (countDup>0)
{
j++;
counts[s.charAt(j)]--;
//make sure the str is with no repeating
if (s.charAt(j) == 1) countDup--;
}
longest = Math.max(...)
LC 76 Minimum Window Substring
- int minLen = Integer.MAX_VALUE; (2^32-1)
- str.substring(a,b) get a substring of str from index=a to index = b-1
e.g. str=abcdefg;
str.substring(4,6) = ef - a++: a doesn’t change until this line finishes.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29//record the length of t, and use countToMatch to see
//whether it's matched while the hash table records the exist times.
int countToMatch = t.length(), left = 0, right = 0;
int head = 0, minLen = Integer.MAX_VALUE;
while (right<s.length())
{
if (counts[s.charAt(right++)]-- > 0)
{
countToMatch--;
}
while (countToMatch == 0)
{
if (right-left < minLen)
{
head = left;
minLen = right - left;
}
//if the character exists in t, the value should be 0;
//or it should be < 0;
if (counts[s.charAt(left++)]++ == 0)
{
countToMatch++;
}
}
return minLen == Integer.MAX_VALUE ? "" : s.substring(head,head+minLen);
}
近期评论