哈希表题目:TinyURL 的加密与解密

题目

标题和出处

标题:TinyURL 的加密与解密

出处:535. TinyURL 的加密与解密

难度

7 级

题目描述

要求

TinyURL 是一种 URL 简化服务。当你输入一个 URL,例如 https://leetcode.com/problems/design-tinyurl 时,它将返回一个简化的 URL,例如 http://tinyurl.com/4e9iAk。设计一个类对 URL 加密和对 TinyURL 解密。

你的加密和解密算法如何设计和运作是没有限制的,你只需要保证一个 URL 可以被加密成一个 TinyURL,并且这个 TinyURL 可以用解密方法恢复成原始的 URL。

实现 Codec \texttt{Codec} Codec 类:

  • Codec() \texttt{Codec()} Codec() 初始化系统对象。
  • String   encode(String   longUrl) \texttt{String encode(String longUrl)} String encode(String longUrl) 根据给定的 longUrl \texttt{longUrl} longUrl 返回 shortUrl \texttt{shortUrl} shortUrl
  • String   decode(String   shortUrl) \texttt{String decode(String shortUrl)} String decode(String shortUrl) 根据给定的 shortUrl \texttt{shortUrl} shortUrl 返回原始的 longUrl \texttt{longUrl} longUrl。题目保证给定的 shortUrl \texttt{shortUrl} shortUrl 由同一个对象加密。

示例

示例 1:

输入: url   =   "https://leetcode.com/problems/design-tinyurl" \texttt{url = "https://leetcode.com/problems/design-tinyurl"} url = "https://leetcode.com/problems/design-tinyurl"
输出: "https://leetcode.com/problems/design-tinyurl" \texttt{"https://leetcode.com/problems/design-tinyurl"} "https://leetcode.com/problems/design-tinyurl"
解释:
Codec   obj   =   new   Codec(); \texttt{Codec obj = new Codec();} Codec obj = new Codec();
String   tiny   =   obj.encode(url); \texttt{String tiny = obj.encode(url);} String tiny = obj.encode(url); // 返回加密后的 tinyurl
String   ans   =   obj.decode(tiny); \texttt{String ans = obj.decode(tiny);} String ans = obj.decode(tiny); // 返回解密后的原始 url

数据范围

  • 1 ≤ url.length ≤ 10 4 \texttt{1} \le \texttt{url.length} \le \texttt{10}^\texttt{4} 1url.length104
  • 题目保证 url \texttt{url} url 是有效的 URL

解法

思路和算法

这道题有多种实现方法,此处提供一种简单的计数实现方法。

维护一个计数器,初始时计数器的值为 0 0 0。每次加密时,将计数器的值加 1 1 1,在一个固定的 URL 前缀后面拼接上更新后的计数器的值,即可生成加密后的 TinyURL。

为了能够从 TinyURL 解密得到原始 URL,需要使用哈希表记录 TinyURL 和原始 URL 的对应关系,因此在加密操作中生成 TinyURL 之后,需要首先将 TinyURL 和 URL 存入哈希表,然后返回 TinyURL。

由于哈希表中记录了 TinyURL 和原始 URL 的对应关系,因此在解密时,只要从哈希表中找到 TinyURL 对应的原始 URL 并返回即可。

代码

public class Codec {
    static final String SHORT_PREFIX = "https://tinyurl.com/";
    Map<String, String> map = new HashMap<String, String>();
    int count = 0;

    public String encode(String longUrl) {
        count++;
        String shortUrl = SHORT_PREFIX + count;
        map.put(shortUrl, longUrl);
        return shortUrl;
    }

    public String decode(String shortUrl) {
        return map.get(shortUrl);
    }
}

复杂度分析

  • 时间复杂度:构造方法和各项操作的时间复杂度都是 O ( 1 ) O(1) O(1)。构造方法为初始化操作,加密操作包括更新计数器、生成 TinyURL、将 TinyURL 和原始 URL 存入哈希表和返回 TinyURL,解密操作为从哈希表中得到 TinyURL 对应的原始 URL 并返回,时间复杂度都是 O ( 1 ) O(1) O(1)。这里将字符串操作的时间视为 O ( 1 ) O(1) O(1)

  • 空间复杂度: O ( n ) O(n) O(n),其中 n n n 是加密和解密的调用次数。需要使用两个哈希表记录每个 TinyURL 对应的原始 URL,哈希表中的元素个数取决于调用次数。

后记

除了使用计数的方法以外,这道题还有其他的实现方法,例如使用非十进制计数、随机生成加密后的 URL、使用哈希函数计算加密后的 URL 等,感兴趣的读者可以自行尝试。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

伟大的车尔尼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值