标签:设计、哈希表、字符串、哈希函数
感受:每次看到设计题,我都有点头疼,不知道怎么做。
结论:
一般先自己想一下,题目要干嘛,自己的话会怎么做。做不出来会看一下题解,前期可以多看、多写、多模仿。
官方题解给了三种,但是我看着decode都是一样的,根据key去取value。只是encode的实现方式不一样,但是思路也是生成key-value
题解一:自增
public class Codec {
private Map<Integer, String> dataBase = new HashMap<Integer,String>();
private int id;
// Encodes a URL to a shortened URL.
// 使用自增id 作为 longUrl 的键,每接收一个longUrl 都将 id 加一,将键值对(id,longUrl) 插入数据库 dataBase,然后返回带有 id 的字符串作为shorUrl。
public String encode(String longUrl) {
id++;
dataBase.put(id,longUrl);
return "https://tinyurl.com/" + id;
}
// Decodes a shortened URL to its original URL.
// 将 shortUrl 转换成对应的 key,然后在数据库 dataBase 中查找key 对应的 longUrl。
public String decode(String shortUrl) {
int p = shortUrl.lastIndexOf('/') + 1;
int key = Integer.parseInt(shortUrl.substring(p));
return dataBase.get(key);
}
}
题解二:哈希生成
public class Codec {
static final int K1 = 1117;
static final int K2 = 1000000007;
private Map<Integer, String> dataBase = new HashMap<Integer, String>();
private Map<String, Integer> urlToKey = new HashMap<String, Integer>();
// 设字符串longUrl 的长度为 n
public String encode(String longUrl) {
if (urlToKey.containsKey(longUrl)) {
return "http://tinyurl.com/" + urlToKey.get(longUrl);
}
int key = 0;
long base = 1;
for (int i = 0; i < longUrl.length(); i++) {
char c = longUrl.charAt(i);
key = (int) ((key + (long) c * base) % K2);
base = (base * K1) % K2;
}
while (dataBase.containsKey(key)) {
key = (key + 1) % K2;
}
dataBase.put(key, longUrl);
urlToKey.put(longUrl, key);
return "http://tinyurl.com/" + key;
}
// 将shortUrl 转换成对应的key,然后在数据库dataBase 中查找key 对应的longUrl。
public String decode(String shortUrl) {
int p = shortUrl.lastIndexOf('/') + 1;
int key = Integer.parseInt(shortUrl.substring(p));
return dataBase.get(key);
}
}