热乎的笔试题目

柠檬微趣笔试题目, 总共四道. 做了两道

 https://leetcode.cn/problems/word-pattern/

第一道题目. 单词规律:

拿到这道题目之初,便想到了很明显的hash映射痕迹在其中. 然后就是字符串解析. 看到s串空格分割,我不由得想到了stringstream. 我放入s串到stringstream对象中, 借助operator>>流出来,可以解析获取到word.    

首先对比左右len 是不是对应的, 如果不对应一定是false  对应之后再判断是不是满足pattern类型的

然后continue: 干他. 这个不是so easy: 拿下

class Solution {
public:
    bool wordPattern(string pattern, string s) {
        int len1 = pattern.size();
        int len2 = 1;
        for (auto& e : s) {
            len2 += (e == ' ');
        }
        if (len1 != len2) return false;
        unordered_map<char, string> mp;
        stringstream ss(s);
        for (int i = 0; i < len1; ++i) {
            char ch = pattern[i];
            string str;
            ss >> str;
            if (mp.find(ch) == mp.end()) {
                mp[ch] = str;
            } else {//已经出现过了, 判断是否匹配
                if (mp[ch] != str) return false;
            }
        }
        return 1;
    }
};

很遗憾: 这个没有完全通过: 

 观察观察, 貌似貌似忽略了一个小小的细节呀: 

需要双向映射: 于是卧槽,这个a 跟着 b 咋不同的字母都映射到了相同的value值,必然不可以呀. 所以我还需要判断的是不能存在重复的value. 但是C++中的hash table 也就是unordered_map 并不存在查找containValue的这种内置函数, 咋搞,反向再来一个map映射value到key呗

class Solution {
public:
    bool wordPattern(string pattern, string s) {
        int len1 = pattern.size();
        int len2 = 1;
        for (auto& e : s) {
            len2 += (e == ' ');
        }
        if (len1 != len2) return false;
        unordered_map<char, string> mp1;
        unordered_map<string, char> mp2;
        stringstream ss(s);
        for (int i = 0; i < len1; ++i) {
            char ch = pattern[i];
            string str;
            ss >> str;
            if (mp1.find(ch) == mp1.end()) {
                mp1[ch] = str;
                if (mp2.find(str) != mp2.end()) return false;
                //已经映射过了, 不是一一映射了, 思考a, b 都对应dog场景
                mp2[str] = ch;
            } else {//已经出现过了, 判断是否匹配
                if (mp1[ch] != str) return false;
            }
        }
        return 1;
    }
};

力扣https://leetcode.cn/problems/next-greater-element-iii/

拿到题目之初,还是最简单的思考了一下, 简单呀,提取每一位元素到数组中,然后对数组中的元素进行有条件交换,最后再提取数组作为结果即可,最初我想的是用一个整形数组算了. 但是后面我一想,为啥我不用string. 先将其直接转换为string 操作不就是相当于数组吗, 最后再转换回到整形即可.

然后我第一个思路诞生了。说白了我就是在右边往左走,走到第一个出现较小的位的num 然后将其交换成后面较大的数字,整体就变大了一点点。为啥从右走, 为啥找第一个出现.

这个不都是为了满足题目的大一点点的要求么?   将大的数往高位换,你肯定尽量的换低位才能尽可能小呀. 所以思路出来了,我找到第一个小的位置换了. 换了之后, 对于换了的位置之后进行一个sort, 升序(高位小数,低位大数,让数据尽可能小).

第一次的swap: 为了保证比原来的数字大. 后面的sort, 为了保证是刚刚大一点

为了找左边第一个小的元素,我自然而然的我想到了单调栈.

class Solution {
public:
    int nextGreaterElement(int n) {
        string numstr = to_string(n);
        stack<int> moreStack;//递增栈
        int posind, ind;
        for (ind = numstr.size()-1; ind>=0; ind--) {
            char ch = numstr[ind];
            if (moreStack.empty() || ch >= numstr[moreStack.top()]) {
                moreStack.push(ind);
                continue;
            }
            posind = ind;//need swap
            while (!moreStack.empty() && ch < numstr[moreStack.top()]) {
                ind = moreStack.top();
                moreStack.pop();
            }
            break;
        }
        if (ind == -1) return -1;
        swap(numstr[ind], numstr[posind]);
        //posind 之后将小的位往前转
        sort(numstr.begin()+posind+1, numstr.end());
        if (stol(numstr) > INT_MAX) {
            return -1;
        }
        return stoi(numstr);
    }
};

单调栈,找右边第一个小于的元素, 或者找第一个大于的元素简直就是神器,用过的人都知道哈哈哈,其实本质就是很简单的. 遥望原理:  你往前看. 肯定只能看到比你高的。比你高的自然不可能是第一个矮的. 那出现的第一个矮的,就是你前面所有哪些高的的后面的第一个矮的

由于存在右边第一个, 而且是单调递增的特性,由配合栈的先进先出,就具备了这一完美的找右边第一个小于或者第一个大于的特性呀. 

猜你喜欢

转载自blog.csdn.net/weixin_53695360/article/details/127575740
今日推荐