23.哀家要长脑子了!

目录

1.290. 单词规律 - 力扣(LeetCode)

 2.532. 数组中的 k-diff 数对 - 力扣(LeetCode)

3.205. 同构字符串 - 力扣(LeetCode)

4.138. 随机链表的复制 - 力扣(LeetCode)

5.599. 两个列表的最小索引总和 - 力扣(LeetCode


1.290. 单词规律 - 力扣(LeetCode)

怎么打简单的标签,我第一反应是无从下手,不知所措。。。

这道题有两个要注意的点:一个是双向映射,一个是字符串中单词的分割

是这样一个思路: 

用两个map,一个map ps记录从pattern到s的映射,一个map sp记录从s到pattern的映射

start代表字符串s中某个单词的开头,end表示结尾

for循环遍历关规律pattern中的每个字母,如果进入循环后,发现单词的起点已经大于s的长度,说明字符串s中的每个单词已经遍历完毕,但是pattern还没有遍历完毕(因为进入了for循环)说明s的长度大于pattern,out。

接下来就是分割单词:当 end小于字符串s的长度并且此时位置上的元素不为空格,说明这个单词还没找完整,end后移继续查找完整。当end大于字符串s的长度,说明字符串s中最后一个单词找完整的;当end小于s的长度,但是此时位置上的元素为空格,说明s中的某一个单词查找完毕。

判断双向映射:如果此时的pattern字符中的ch已经在ps中存在,但是这个ch所映射的单词跟我们上面提取的单词不一样。out。或者此时的单词作为的索引所映射的字符跟我们现在遍历到的字符不一样,out。

一定要两个映射表都判断一下,因为要判断双向一致,比如下面这个样例

pattern = "abba"  s = "dog dog dog dog"

 如果只判断一个映射表ps的话:只能知道a对应dog,b也对应dog,是对的,不会返回false

但实际上我们需要唯一的映射,a对应dog,b不能对应dog了,out。

判断完之后:将此时新的这个映射关系加入到两边的映射表中

更新单词的起点终点:新一个单词的起点是上一个单词终点的下一位(单词的起点终点唯一同一位置开始遍历,起点索引不懂,终点索引去找终点

规律pattern遍历完毕后,如果最后一轮遍历所更新的起点的索引正好等于字符串s的长度加1。说明单词个数正好也等于规律中的字符个数。

class Solution {
public:
    bool wordPattern(string pattern, string s) {
        unordered_map<char, string> ps;
        unordered_map<string, char> sp;
        int n = pattern.size(), m = s.size(), start = 0, end = 0;
        string word;
        char ch;
        for(int i = 0; i < n; i++){
            if(start > m) return false;
            while(end < m && s[end] != ' ') end++;
            word = s.substr(start, end - start);    
            ch = pattern[i];
            if(ps.count(ch) && ps[ch] != word || sp.count(word) && sp[word] != ch){
                return false;
            }
            ps[ch] = word;
            sp[word] = ch;
            start = end + 1;
            end = start;  
        }
        return start == m + 1;
    }
};
 2.532. 数组中的 k-diff 数对 - 力扣(LeetCode)

 首先我自己做就是用个set,然后加上差值看set中有没有对应需要的值,有点像前几天的两数之和,但是这样的话处理0或者负数元素就会出错。因为k是题目要求的差值的绝对值。

| nums[i] - nums[j] | = k 

k为正数:nums[j] = nums[i] - k

k为负数:nums[j] = nums[i] + k

是这样的:用两个set,一个set用来满足条件的数值对,到时候返回它的长度就好了,另一个set用来判断此时正在遍历的元素满足题目条件所需对应数字num-k有没有在原数组中(题目有要求)

num是此时数组正在遍历的元素,num-k是满足题目要求所对应的数字。如果num-k在vis中,说明num是正数,并且原数组nums中有这样两个数字可以构成一组数对来满足题目要求。把对应的num-k数字放到结果数组中。如果num+k在数组中,说明num是负数,并且原数组nums中有这样两个数字可以构成一组数对来满足题目要求。把对应的num数字放到结果数组中。最后把当前正在遍历的num放入vis中,代表原数组中有这个数字,可以参与构成数对。每次都放比较小的那个元素,其实我有点疑惑,但是还没有彻底弄懂了。

class Solution {
public:
    int findPairs(vector<int>& nums, int k) {
        unordered_set<int> res;
        unordered_set<int> vis;
        for(const int& num : nums){
            if(vis.count(num - k)){    
                res.insert(num - k);
            }
            if(vis.count(num + k)){
                res.insert(num);
            }
            vis.insert(num);
        }
        return res.size();
    }
};
3.205. 同构字符串 - 力扣(LeetCode)

跟第一题一样的思路,但是我先判断了数组长度,不一样最喜欢i直接返回。out

class Solution {
public:
    bool isIsomorphic(string s, string t) {
        int n = s.size(), m = t.size();
        unordered_map<char, char> st;
        unordered_map<char, char> ts;
        if(n != m) return false;
        for(int i = 0; i < n; i++){
            if(st.count(s[i]) && st[s[i]] != t[i] || ts.count(t[i]) && ts[t[i]] != s[i] ){
                return false;
            }
            st[s[i]] = t[i];
            ts[t[i]] = s[i];
        }
        return true; 
    }
};
4.138. 随机链表的复制 - 力扣(LeetCode)

 其实我觉得这道题还挺有意思的,就是这个random的存在,一开始我还没看懂这个题目有什么不同,我发现有时候我老是看不出题目的意思,读不懂题意。

这个题目关键的就是这个random,我们复制链表的时候,可能此时这个结点random指向的结点还没有被创建,如果被创建了又应该怎样记录呢。此时就用哈希表。

首先建立一个 还没有任何关系的哈希表,里面只是一个个结点,结点之间没有任何的指针指向。

接着用指向原链表的cur指针开始建立映射关系了。

 哎哟,其实我还是有点懵懵懂懂,模模糊糊

class Solution {
public:
    Node* copyRandomList(Node* head) {
        if(!head) return head;
        Node *cur = head;
        unordered_map<Node*, Node*> map;
        while(cur){
            map[cur] = new Node(cur->val);
            cur = cur->next;
        }    
        cur = head;
        while(cur){
            map[cur]->next = map[cur->next];
            map[cur]->random = map[cur->random];
            cur = cur->next;     
        }
        return map[head];
    }
};
5.599. 两个列表的最小索引总和 - 力扣(LeetCode)

 用一个map来操作记录他们之间的索引关系。把lsit1中的元素作为map的索引,list1中元素的下标作为map中的值。然后list2中的元素作为索引去操作去匹配。

class Solution {
public:
    vector<string> findRestaurant(vector<string>& list1, vector<string>& list2) {
        unordered_map<string, int> map;
        for(int i = 0; i < list1.size(); i++){
            map[list[i]] = i;
        }
        int sum = INT_MAX;
        vector<string> res;
        for(int i = 0; i < list2.size(); i++){
            // 如果有相同的餐厅
            if(map.count(list2[i])){
                int j = map[list2[i]];
                // 如果发现有更小的索引和
                if(i + j < sum){
                    // 清空原来记录的结果
                    res.clear();
                    // 记录此时更小的索引和所对应得餐厅
                    res.push_back(list2[i]);
                    // 记录新的索引和
                    sum = i + j;
                }    
                // 如果索引和是最小的
                else if(i + j == sum){
                    // 记录一下辣
                    res.push_back(list2[i]);        
            }            
        }
        return res;
    }
};

啊啊啊啊,我这被饼干操纵的一生。。。

是这样,昨天我晚饭吃的一个茶叶蛋,一包徐福记岩板烧,一个鸡蛋香松面包,然后昨天我又想逃避vue,又看不下软考,我就去吃了个烤全翅,好难吃,我还吃了个徐福记三包饼干,然后我又吃了个芋泥饼干,我又吃了徐福记三包饼干和一个牛肉干,还有四分之三的早茶饼干。嗯。。今天早上吃的是一碗蛋炒粉(放了蒜末,酸豆角,葱和很多很多的醋)全吃完了,嗯。还有徐福记三包饼干,一个香干,一个盐焗鸭蛋,昨天剩下的四分之一饼干,还有一瓶豆奶。小姐姐你挺能吃的。。

5.3开始写的。。。 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值