forked from mehul-1607/Leetcode
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path_535.java
135 lines (118 loc) · 5.5 KB
/
_535.java
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package com.fishercoder.solutions;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
/**
* 535. Encode and Decode TinyURL
*
* TinyURL is a URL shortening service where you enter a URL such as https://leetcode.com/problems/design-tinyurl
* and it returns a short URL such as http://tinyurl.com/4e9iAk.
* Design the encode and decode methods for the TinyURL service.
* There is no restriction on how your encode/decode algorithm should work.
* You just need to ensure that a URL can be encoded to a tiny URL and the tiny URL can be decoded to the original URL.
Note: Do not use class member/global/static variables to store states. Your encode and decode algorithms should be stateless.
*/
public class _535 {
public static class Solution1 {
/**
* Simple counter approach
* Analysis:
* The range of URLs that can be decoded is limited by the range of Integer.
* If excessively large number of URLs have to be encoded, after the range of Integer is exceeded,
* integer overflow could lead to overwriting previous URL's encodings.
* The length of the URL isn't necessary shorter than incoming URL.
* One potential security issue with this problem is that it's very easy to predict the next code generated,
* since this pattern is very easy to be detected.
*/
public class Codec {
int i = 0;
Map<Integer, String> map = new HashMap();
public static final String PREFIX = "http://tinyurl/";
public String encode(String longUrl) {
map.put(i, longUrl);
return PREFIX + i++;
}
public String decode(String shortUrl) {
return map.get(Integer.parseInt(shortUrl.substring(PREFIX.length())));
}
}
}
public static class Solution2 {
/**
* Use Java built-in HashCode
* Analysis:
* hashCode() does NOT generate unique codes for different strings, collision might happen.
* As the number of URLs increase, the probability of getting collision increases which leads to failure.
*/
public class Codec {
Map<Integer, String> map = new HashMap<>();
public static final String PREFIX = "http://tinyurl/";
// Encodes a URL to a shortened URL.
public String encode(String longUrl) {
/**I don't need to create a local variable to cache longUrl.hashCode()
* since Java's String cache it already. :) Look at its source code.*/
map.put(longUrl.hashCode(), longUrl);
return PREFIX + longUrl.hashCode();
}
// Decodes a shortened URL to its original URL.
public String decode(String shortUrl) {
return map.get(Integer.parseInt(shortUrl.substring(PREFIX.length())));
}
}
}
public static class Solution3 {
/**Use a random number*/
Map<Integer, String> map = new HashMap<>();
Random random = new Random();
public static final String PREFIX = "http://tinyurl/";
// Encodes a URL to a shortened URL.
public String encode(String longUrl) {
int num = random.nextInt(Integer.MAX_VALUE);
while (map.containsKey(num)) {
num = random.nextInt(Integer.MAX_VALUE);
}
map.put(num, longUrl);
return PREFIX + num;
}
// Decodes a shortened URL to its original URL.
public String decode(String shortUrl) {
return map.get(Integer.parseInt(shortUrl.substring(PREFIX.length())));
}
}
public static class Solution4 {
/**
* Use a random but fixed length encoding
* Analysis:
* 1. This is the most optimal solution so far.
* 2. The number of URLs that can be encoded can be as big as Math.pow((10 + 26*2), FIXED_LENGTH)
* 3. The length of the shortened URL is fixed at a certain length, which could be a significant reduce for large URLs
* 4. The performance of this scheme is pretty good, due to much smaller probability of encountering collision
* 5. Predicting pattern/encoding isn't possible in this case since random numbers are used.
*/
Map<String, String> map = new HashMap<>();
public static final String PREFIX = "http://tinyurl/";
public static final int FIXED_LENGTH = 7;
Random random = new Random();
String alphabet = "0123456789abcdefghijklmnopgrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
// Encodes a URL to a shortened URL.
public String encode(String longUrl) {
String shortKey = getRandomFixedLengthKey();
while (map.containsKey(shortKey)) {
shortKey = getRandomFixedLengthKey();
}
map.put(shortKey, longUrl);
return PREFIX + shortKey;
}
private String getRandomFixedLengthKey() {
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < FIXED_LENGTH; i++) {
stringBuilder.append(alphabet.charAt(random.nextInt(alphabet.length())));
}
return stringBuilder.toString();
}
// Decodes a shortened URL to its original URL.
public String decode(String shortUrl) {
return map.get(shortUrl.substring(PREFIX.length()));
}
}
}