二.字符串(20)535. TinyURL 的加密与解密

535. TinyURL 的加密与解密

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

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

实现 Solution 类:

Solution() 初始化 TinyURL 系统对象。
String encode(String longUrl) 返回 longUrl 对应的 TinyURL 。
String decode(String shortUrl) 返回 shortUrl 原本的 URL 。题目数据保证给定的 shortUrl 是由同一个系统对象加密的。
 

示例:

输入:url = "https://leetcode.com/problems/design-tinyurl"
输出:"https://leetcode.com/problems/design-tinyurl"

解释:
Solution obj = new Solution();
string tiny = obj.encode(url); // 返回加密后得到的 TinyURL 。
string ans = obj.decode(tiny); // 返回解密后得到的原本的 URL 。
 

提示:

1 <= url.length <= 104
题目数据保证 url 是一个有效的 URL

 

前言
题目不要求相同的 URL 必须加密成同一个TinyURL,因此本文的方法不满足相同的 URL 加密成同一个TinyURL。如果想要实现相同的 URL 加密成同一个TinyURL,则额外保存一个从 URL 到 TinyURL 的映射。

方法一:自增
Encode 函数

使用自增id 作为longUrl 的键,每接收一个longUrl 都将id 加一,将键值对 (id,longUrl) 插入数据库 dataBase,然后返回带有 id 的字符串作为 shortUrl。

Decode 函数

将shortUrl 转换成对应的key,然后在数据库dataBase 中查找key 对应的longUrl。

public class Codec {

    private Map<Integer, String> dataBase = new HashMap<Integer, String>();
    private id;
    
    // Encodes a URL to a shortened URL.
    public String encode(String longUrl) {
        id++;
        dataBase.put(id,longUrl);
        return "http://tinyurl.com/"+id;
    }

    // Decodes a shortened URL to its original URL.
    public String decode(String shortUrl) {
        int p = shortUrl.lastIndexOf('/') + 1;//lastIndexOf的结果是该字符的下标。下标从0开始。
        int key = Integer.parseInt(shortUrl.substring(p));//substring是从该下标开始的字符串。
        return dataBase.get(key);
    }
}

// Your Codec object will be instantiated and called as such:
// Codec codec = new Codec();
// codec.decode(codec.encode(url));

 

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>();

    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;
    }



    public String decode(String shortUrl) {//解码
        int p = shortUrl.lastIndexOf('/') + 1;
        int key = Integer.parseInt(shortUrl.substring(p));
        return dataBase.get(key);
    }
}

方法三:随机生成
Encode 函数

使用一个随机生成的整数作为longUrl 的key,如果 key 已经重复,那么不断尝试随机生成整数,直到 key 唯一。将键值对 (key,longUrl) 插入数据库dataBase,然后返回带有key 的字符串作为 shorUrl。

Decode 函数

将 shortUrl 转换成对应的key,然后在数据库dataBase 中查找key 对应的longUrl。

public class Codec {
    private Map<Integer, String> dataBase = new HashMap<Integer, String>();
    private Random random = new Random();

    public String encode(String longUrl) {
        int key;
        while (true) {
            key = random.nextInt();
            if (!dataBase.containsKey(key)) {
                break;
            }
        }
        dataBase.put(key, longUrl);
        return "http://tinyurl.com/" + key;
    }

    public String decode(String shortUrl) {
        int p = shortUrl.lastIndexOf('/') + 1;
        int key = Integer.parseInt(shortUrl.substring(p));
        return dataBase.get(key);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值