Leecode: 658, 535, 32

658. Find K Closest Elements

题目描述

Given a sorted array, two integers k and x, find the k closest elements to x in the array. The result should also be sorted in ascending order. If there is a tie, the smaller elements are always preferred.

Example 1:

Input: [1,2,3,4,5], k=4, x=3
Output: [1,2,3,4]

Example 2:

Input: [1,2,3,4,5], k=4, x=-1
Output: [1,2,3,4]

Note:

  1. The value k is positive and will always be smaller than the length of the sorted array.
  2. Length of the given array is positive and will not exceed 104
  3. Absolute value of elements in the array and x will not exceed 104


UPDATE (2017/9/19):
The arr parameter had been changed to an array of integers (instead of a list of integers). Please reload the code definition to get the latest changes.

解决思路

首先二分查找 x 在已排序的数组中对应的位置, 再设置一个 distance 开始双向遍历.

代码

int find_init_pos(vector<int>& arr, int val){
    // find the first element larger or equal than val
    int left = 0, right = arr.size() - 1;
    while(left < right){
        int mid = (left + right) >> 1;
        if( val < arr[mid]) right = mid;
        else if ( val > arr[mid]) left = mid + 1;
        else return mid;
    }
    if(arr[left] >= val)    return left;
    return arr.size() - 1;
}

class Solution {
public:
    vector<int> findClosestElements(vector<int>& arr, int k, int x) {
        vector<int> result;
        int distance = 0;
        int left = 0, right = 0;
        left = find_init_pos(arr, x) - 1;
        right = left + 1;
        cout<<"left = "<<left<<" right = "<<right<<endl;
        while(k > 0){
            if( left >= 0 && abs(x - arr[left]) <= distance){
                result.push_back(arr[left]);
                cout<<"Push "<<arr[left]<<" k = "<<k<<endl;
                --left;
                --k;
                continue;
            }
            else if( right <= arr.size()-1 && abs(arr[right] - x) <= distance){
                result.push_back(arr[right]);
                cout<<"Push "<<arr[right]<<" k = "<<k<<endl;
                ++right;
                --k;
                continue;
            }
            else{
                ++distance;
            }

        }
        sort(result.begin(), result.end());
        return result;
    }
};

535. Encode and Decode TinyURL

问题描述

Note: This is a companion problem to the System Design problem: Design 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.

解题思路

可以构造两个Map, 一个是从 longUrl -> shortUrl 的, 另一个是从 shortUrl -> id 的. 这样可以保证访问速度.

另外一种想法就是字符串Hash, 不过这样就麻烦点, 需要解决冲突之类, 不如直接通过保存两个dict方便

代码

class Solution{
public:
    string dict = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    int id = 0;
    unordered_map m;  //key is longURL, value is shortURL
    unordered_map idm;  //key is id in DB, value is longURL
    // Encodes a URL to a shortened URL.
    string encode(string longUrl) {
        if(m.find(longUrl) != m.end())return m[longUrl];
        string res = "";
        id++;
        int count = id;
        while(count > 0)
        {
            res = dict[count%62] + res;
            count /= 62;
        }
        while(res.size() < 6)
        {
            res = "0" + res;
        }
        m[longUrl] = res;
        idm[id] = longUrl;
        return res;
    }

    // Decodes a shortened URL to its original URL.
    string decode(string shortUrl) {
        int id = 0;
        for(int i = 0; i < shortUrl.size(); i++)
        {
            id = 62*id + (int)(dict.find(shortUrl[i]));
        }
        if(idm.find(id) != idm.end())return idm[id];
        return "";
    }
};

32. Longest Valid Parentheses

问题描述

Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) parentheses substring.

Example 1:

Input: "(()"
Output: 2
Explanation: The longest valid parentheses substring is "()"

Example 2:

Input: ")()())"
Output: 4
Explanation: The longest valid parentheses substring is "()()"

解决思路

十分机智的一道题目,一看到这种匹配的问题就应该能够迅速想到用栈来解决. 包括编译原理的时候也学到了这方面的知识,包括如何匹配算数表达式等等.

这题比较机智的地方就是.之前我一直是想的往 stack 中塞 true or false, 然后匹配则 pop, 然后对应的 count += 2, 再想办法界定当前在匹配的括号是否与之前的那段相连. 但是这样是行不通的, 就是我通过单纯地push true or false 是没办法界定整个的起点终点的, 考虑一种情况: (()()), 这种时候不仅仅是后面那对括号是否与前面括号相连,外面还一个大括号.

所以转而想到的思路就是往中push括号的index, 最关键的地方是找出上一个不能够成功匹配的位置, 最开始的位置是-1, 具体可以参考官方的solution, 给的很完整:
https://leetcode.com/problems/longest-valid-parentheses/solution/

代码

class Solution {
public:
    // 找到上一个没能完成匹配的位置
    int longestValidParentheses(string s) {
        stack<int> pareStack;
        int ans = 0, len = 0;
        pareStack.push(-1);
        for (int i = 0; i < s.size(); ++i) {
            if(s[i] == '('){
                pareStack.push(i);
            }
            else{
                if(pareStack.empty()){
                    continue;
                }
                else{
                    pareStack.pop();
                    if(pareStack.empty()){
                        pareStack.push(i);
                    }
                    len = i - pareStack.top();
                    ans = max(ans, len);
                }
            }
        }
        return ans;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值