[代码随想录]基本数据结构篇

news2024/11/18 1:40:53

文章目录

  • 1.数组篇
    • 1.1 704-二分查找
    • 1.2 27-移除数组
    • 1.3 977-有序数组的平方
    • 1.4* 209--长度最小的子数组(滑动窗口)
    • 1.5* 59-螺旋矩阵II
  • 2. 链表篇
    • 2.1 203-移除链表元素
    • 2.2 707-设计链表
    • 2.3 206-反转链表
    • 2.4* 24-两两交换链表中的节点(跳针)
    • 2.5* 19-删除链表的倒数第N个节点(快慢指针)
    • 2.6* 链表相交
    • 2.7 142-环形链表II
  • 3. 哈希篇
    • 3.1 242-有效的字母异位词
    • 3.2* 1002-查找共用字符
    • 3.3 349-两个数组的交集
    • 3.4 202-快乐数
    • 3.5 1-两数之和
    • 3.6* 454-四数相加II
    • 3.7 383-赎金信
  • 4. 双指针篇
    • 4.1 15-三数之和(双指针)
    • 4.2 18-四数之和
  • 5. 字符串篇
    • 5.1 344-反转字符串
    • 5.2 541-反转字符串II
    • 5.3* 151-反转字符串中的单词
    • 5.4 182-动态口令
    • 5.5* 459-重复的子字符串
    • 5.6* 28-找出字符串中第一个匹配项的下标(KMP)
  • 6. 栈和队列篇
    • 6.1 232-用栈实现队列
    • 6.2 225-用队列实现栈
    • 6.3 20-有效的括号
    • 6.4 1047-删除字符串中的所有相邻重复项
    • 6.5 150-逆波兰表达式求值
    • 6.6* 239-滑动窗口最大值(双端队列)
    • 6.7* 347-前K个高频元素(优先级队列)

1.数组篇


1.1 704-二分查找

704

在这里插入图片描述

class Solution {
public:
    int search(vector<int>& nums, int target)
    {
        int begin =0;
        int end = nums.size()-1;
        int mid;
        while(begin <= end)  // -1,0,3,5,9,12
        {
            mid = begin+(end - begin)/2;
            if(nums[mid] < target)
                begin = mid+1;
            else if(nums[mid] > target)
                end = mid-1;
            else
                return mid;          
           
        }
        return -1;
    }
};

1.2 27-移除数组

27

在这里插入图片描述

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int fast = 0,slow = 0;
        while(fast != nums.size())
        {
            if(nums[fast] == val)
            {
                fast++;
            }
            else
            {
                nums[slow] = nums[fast];
                fast++;
                slow++;
            }
        }
        return slow;
    }
};

1.3 977-有序数组的平方

977

在这里插入图片描述

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        int left = 0;
        int right = nums.size()-1;
        int flag = right;
        vector<int> v(right+1);
        while(left <= right)
        {
            int leftq = nums[left]*nums[left] ;
            int rightq = nums[right]*nums[right];
            if(rightq >= leftq)
            {
                v[flag--] = rightq;
                right--;
            }
            else
            {
                v[flag--] = leftq;
                left++;
            }
        }
        return v;
    }
};

1.4* 209–长度最小的子数组(滑动窗口)

209
在这里插入图片描述

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int left = 0,right = 0,sum = 0,min = INT_MAX;
        while(right < nums.size())
        {
            sum+=nums[right]; //统计左右指针之间的数据和
            while(sum >= target) //当期间数据大于等于target时进入,左指针向右移动
            {
                int newmin = right - left + 1;
                min = newmin < min ? newmin : min; //期间数据个数
                sum -= nums[left];
                left++;
            }
            right++;
        }
        return min==INT_MAX ? 0 : min;
    }
};

时间复杂度为 O(N)


1.5* 59-螺旋矩阵II

59

在这里插入图片描述

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> vv(n,vector<int>(n,0));
        int num = 0; //计数
        int k = 0; //活跃数字(填数坐标)
        int i = 0; //k依附坐标
        int j = n - 1; //k依附坐标

        while(i <= j) //当为奇数时会k == i == j,循环进入却没有填入操作
        {
            k = i;
            while(k < j)
                vv[i][k++] = ++num;
            
            k = i;
            while(k < j)
                vv[k++][j] = ++num;

            k = j;
            while(k > i)
                vv[j][k--] = ++num;

            k = j;
            while(k > i)
                vv[k--][i] = ++num;

            ++i;
            --j;
        }
        if(n%2)
            vv[(n-1)/2][(n-1)/2] = ++num;

        return vv;
    }
};

2. 链表篇

2.1 203-移除链表元素

203

在这里插入图片描述

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:

    void Recursion(ListNode* prev,ListNode* cur,int val)
    {
        if(cur == nullptr)
            return;
        Recursion(cur,cur->next,val);
        if(cur->val == val)
        {
            ListNode* tmp = cur;
            prev->next = cur->next;
            cur = cur->next;
            delete tmp;
        }
    }
    ListNode* removeElements(ListNode* head, int val) {
        while(head != nullptr && head->val == val)
            head = head->next;
        if(head != nullptr && head->next != nullptr)
            Recursion(head,head->next,val);
        return head;
    }
};

2.2 707-设计链表

707

在这里插入图片描述

class MyLinkedList {
public:

    struct ListNode
    {
        int val;
        ListNode* next;
        ListNode(int val)
            :val(val)
            ,next(nullptr)
        {}
    };

    MyLinkedList() 
    {
        head = new ListNode(0);
        size = 0;
    }
    
    int get(int index) {
        if(size <= index) //判断是否可以进行循环
            return -1;

        ListNode* cur = head->next;
        while(index--)
            cur = cur->next;
        return cur->val;
    }
    
    void addAtHead(int val) {
        addAtIndex(0,val);
    }
    
    void addAtTail(int val) {
        addAtIndex(size,val);
    }
    
    void addAtIndex(int index, int val) {
        if(size < index) //判断是否可以进行循环
            return;
        ListNode* newnode = new ListNode(val);
        ListNode* cur = head;
        while(index--)
            cur = cur->next; //cur 在index前
        newnode->next = cur->next;
        cur->next = newnode;
        size++;
    }
    
    void deleteAtIndex(int index) {
        if(size <= index)
            return;

        ListNode* cur = head;
        while(index--)
            cur = cur->next;
        ListNode* del = cur->next;
        ListNode* delnext = del->next;
        cur->next = delnext;
        delete del;
        size--;
    }

private:
    ListNode* head; //头节点
    int size;
};

/**
 * Your MyLinkedList object will be instantiated and called as such:
 * MyLinkedList* obj = new MyLinkedList();
 * int param_1 = obj->get(index);
 * obj->addAtHead(val);
 * obj->addAtTail(val);
 * obj->addAtIndex(index,val);
 * obj->deleteAtIndex(index);
 */

2.3 206-反转链表

206

在这里插入图片描述
在这里插入图片描述

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    void Recursion(ListNode*&head,ListNode* prev,ListNode* cur)
    {
        if(!cur->next)
        {
            head = cur;
            head->next = prev;
            return;
        }
        Recursion(head,cur,cur->next);
        cur->next = prev;
    }
    ListNode* reverseList(ListNode* head) {
        if(!head || !head->next)
            return head;
        Recursion(head,nullptr,head);
        return head;
    }
};

2.4* 24-两两交换链表中的节点(跳针)

24

在这里插入图片描述

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    void Recursion(ListNode*& head,ListNode* prev,ListNode* cur,ListNode* next)
    {
        if(cur == nullptr || cur->next == nullptr) //当到头时,也就是cur在倒数第二个
            return;
        Recursion(head,cur->next,cur->next->next,next); //next一直停留,为第一组第二个
        next = cur->next; //next置为未交换前的后一组的第二个,隔指
        if(prev == nullptr) //执行初始最后一次递归
            head = next;
        else
            prev->next = next;
            
        cur->next = next->next;
        next->next = cur;
        return;
    }

    ListNode* swapPairs(ListNode* head) 
    {
        if(head == nullptr || head->next == nullptr) //如果只有<两个直接return
            return head;
        Recursion(head,nullptr,head,head->next); //prev当作空
        return head;
    }
};

2.5* 19-删除链表的倒数第N个节点(快慢指针)

19

在这里插入图片描述
在这里插入图片描述

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    //void Reucursion(ListNode* prev,ListNode* cur)
    //{
    //    
    //} 1 2 3 4 5 6 7 8
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode* fast = head;
        ListNode* slow = head;
        while(n--) 
            fast = fast->next; //fast先走,然后再走
        if(!fast) //fast如果走到头了,倒过来就说明等同于头删
        {
            head = head->next;
            delete slow;
            return head;
        }

        while(fast->next) //fast第二次行动,直到走到尾
        {
            fast = fast->next;
            slow = slow->next;
        }
        //此时slow位置就是要删除节点的上一位
        //开始删除
        ListNode* tmp = slow->next;
        slow->next = tmp->next;
        delete tmp;
        
        return head;
    }
};

2.6* 链表相交

链表相交

在这里插入图片描述
在这里插入图片描述

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        if(!headA || !headB)
            return nullptr;
        ListNode* pa = headA,* pb = headB;
        while(pa!=pb)
        {
            pa = pa==nullptr? headB : pa->next;
            pb = pb==nullptr? headA : pb->next;
        }
        return pa;
    }
};

2.7 142-环形链表II

142

在这里插入图片描述
在这里插入图片描述

方法一:哈希表

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        unordered_set<ListNode*> circle;
        while(head)
        {
            if(circle.count(head))
                return head;
            circle.insert(head);
            head = head->next;
        }
        return nullptr;
    }
};

时间复杂度:O(N),其中 N 为链表中节点的数目。我们恰好需要访问链表中的每一个节点。
空间复杂度:O(N),其中 N 为链表中节点的数目。我们需要将链表中的每个节点都保存在哈希表当中。

方法二:快慢指针

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        ListNode *slow = head, *fast = head;
        while (fast) 
        {
            slow = slow->next;

            if(!fast->next)
                return nullptr;
            fast = fast->next->next;
            if(fast == slow)
            {
                ListNode* cmcross = head;
                while(cmcross != slow)
                {
                    slow = slow->next;
                    cmcross = cmcross->next;
                }
                return cmcross;
            }
        }
        return nullptr;
    }
};

时间复杂度:O(N)
空间复杂度:O(1)

fast走两步,slow走一步,相遇后:头节点和slow一起向前走,相遇即为循环节点


3. 哈希篇

3.1 242-有效的字母异位词

242

在这里插入图片描述

class Solution {
public:
    bool isAnagram(string s, string t) {
        int record[26] = {0};
        for(auto& e : s)
            record[e-'a']++;
        for(auto& e : t)
            record[e-'a']--;
        for(auto& e : record)
        {
            if(e > 0 || e < 0)
                return false;
        }
        return true;
    }
};

时间复杂度:O(n),其中 n 为 s的长度。
空间复杂度:O(S),其中 S 为字符集大小,此处 S=26


3.2* 1002-查找共用字符

1002

在这里插入图片描述

class Solution {
public:
    vector<string> commonChars(vector<string>& words) {
        int record[26] = {0};
        int size = words.size(); // 判断几个字符串
        vector<string> vs;

        for (auto e : words[0])
            record[e - 'a']++;

        for (int i = 1; i < size; ++i) // 修改为从1遍历到size-1
        {
            // 用临时数组存储当前单词中字符的出现次数
            int temp[26] = {0}; 
            for (auto e : words[i])
                temp[e - 'a']++;
                
            // 更新record数组,保留每个字符在所有单词中的最小出现次数
            for (int j = 0; j < 26; ++j)
                record[j] = min(record[j], temp[j]);
        }

        for (int i = 0; i < 26; ++i)
        {
            while (record[i] > 0)
            {
                // 将字符插入到vs中,出现次数由record[i]控制
                vs.push_back(string(1, 'a' + i));
                record[i]--;
            }
        }

        return vs;
    }
};

3.3 349-两个数组的交集

349

在这里插入图片描述

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> start(nums1.begin(),nums1.end());
        unordered_set<int> result; //去重
        for(int num : nums2)
        {
            if(start.find(num) != start.end())
                result.insert(num);
        }
        return vector<int>(result.begin(),result.end());
    }
};

当数组数据确认量少时

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> result_set; // 存放结果,之所以用set是为了给结果集去重
        int hash[1005] = {0}; // 默认数值为0
        for (int num : nums1) // nums1中出现的字母在hash数组中做记录
            hash[num] = 1;
            
        for (int num : nums2)  // nums2中出现话,result记录
            if (hash[num] == 1) 
                result_set.insert(num);
           
        return vector<int>(result_set.begin(), result_set.end());
    }
};

3.4 202-快乐数

202

在这里插入图片描述

class Solution {
public:
    int get(int num)
    {
        int sum = 0;
        while (num)
        {
            sum += (num % 10) * (num % 10);
            num /= 10;
        }
        return sum;
    }
    bool isHappy(int n) {
        unordered_set<int> us;
        int tmp = n; // 使用tmp保存当前的数值
        while (tmp != 1 && us.find(tmp) == us.end()) // 当tmp变为1或出现循环时停止
        {
            us.insert(tmp);
            tmp = get(tmp);
        }
        return tmp == 1; // 如果tmp最终等于1,说明是快乐数,返回true,否则返回false
    }
};

3.5 1-两数之和

1
在这里插入图片描述
在这里插入图片描述

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int,int> um; //key为值,value为坐标
        for(int i = 0; i < nums.size(); ++i)
        {
            auto it = um.find(target - nums[i]);
            if(it != um.end())
                return {i,it->second};

            um.insert(make_pair(nums[i],i));
        }
        return {};
    }
};

T:O(N) S:O(N)


3.6* 454-四数相加II

454

在这里插入图片描述

class Solution {
public:
    int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
        unordered_map<int,int> um; //key为值,value为出现次数
        for(int num1 : nums1)
            for(int num2 : nums2)
                um[num1+num2]++;

        int count = 0;
        for(int num3 : nums3)
            for(int num4 : nums4)
                if(um.find(0-(num3+num4)) != um.end())
                    count+=um[(0-(num3+num4))];
        return count;
    }
};

3.7 383-赎金信

383

在这里插入图片描述

class Solution {
public:
    bool canConstruct(string ransomNote, string magazine) {
        int hash[26] = {0};
        for(char e : magazine)
            hash[e - 'a']++;
        for(char e : ransomNote)
            if(--hash[e-'a'] < 0)
                return false;
        return true;
    }
};

4. 双指针篇

4.1 15-三数之和(双指针)

15

在这里插入图片描述

哈希其实过于复杂,实现起来不如双指针

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        int size = nums.size();
        sort(nums.begin(),nums.end());
        vector<vector<int>> vv;
        for(int i = 0; i < size - 2; ++i) //i为固定的数据
        {
            //为避免重复答案,对固定数据进行判断
            if(i > 0 && nums[i] == nums[i-1])
                continue; 
            
            int left = i+1; //中间数据
            int right = size-1; //末尾数据

            while(left < right)
            {
                int sum = nums[i] + nums[left] + nums[right];
                if(sum > 0)
                    right--;
                else if(sum < 0)
                    left++;
                else
                {
                    vv.push_back({nums[i] , nums[left] , nums[right]});

                    //为了避免重复答案,要对下一组数据进行判断
                    while(left<right && nums[left] == nums[left+1])
                        left++;
                    while(left<right && nums[right] == nums[right-1])
                        right--;
                    left++;
                    right--;
                }
            }
        }
        return vv;
    }
};

4.2 18-四数之和

18

在这里插入图片描述

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        sort(nums.begin(),nums.end());
        vector<vector<int>> ans;
        int size = nums.size();
        for(int i = 0;i<size;++i) //固定第一个
        {
            if(i>0&&nums[i-1] == nums[i])
                continue;
            for(int j = i+1;j<size;++j) //固定第二个
            {
                if(j>i+1&&nums[j-1] == nums[j]) //j>i+1,防止 2 2 2 2 情况
                    continue;
                int left = j+1;
                int right = size-1;
                while(left<right)
                {
                    long long sum =(long long)nums[i]+nums[j]+nums[left]+nums[right];
                    if(sum < target)
                        left++;
                    else if(sum > target)
                        right--;
                    else
                    {
                        ans.push_back({nums[i],nums[j],nums[left],nums[right]});
                        while(left<right && nums[left] == nums[left+1])
                            left++;
                        while(left<right && nums[right] == nums[right-1])
                            right--;
                        right--;
                        left++;
                    }
                }
            }
        }
        return ans;
    }
};

5. 字符串篇

5.1 344-反转字符串

344

在这里插入图片描述

reverse函数也可以

class Solution {
public:
    void reverseString(vector<char>& s) {
        int size = s.size();
        for(int left = 0,right = size-1 ; left < right ; ++left,--right)
            swap(s[left],s[right]);
    }
};

5.2 541-反转字符串II

541

在这里插入图片描述

class Solution {
public:
    string reverseStr(string s, int k) {
        for (int i = 0; i < s.size(); i += (2 * k)) 
        {
            if (i + k <= s.size()) 
                reverse(s.begin() + i, s.begin() + i + k );
            else
                reverse(s.begin() + i, s.end());
        }
        return s;
    }
};

5.3* 151-反转字符串中的单词

151

在这里插入图片描述
在这里插入图片描述

class Solution {
public:
    string reverseWords(string s) {
        while(s[0] == ' ')
            s.erase(s.begin()); //去除开头多余空格
        reverse(s.begin(),s.end());//blue is sky the
        while(s[0] == ' ')
            s.erase(s.begin()); //去除开头多余空格

        int count = 0, size = 0, flag = 0;
        for(int i =0 ; i < s.size();++i)
        {
            count++; //表示当前为第几个字符
            size++; //表示这个单词有几个字符
            if(s[i] == ' ')
            {
                reverse(s.begin()+flag, s.begin()+flag+size-1);
                flag = count; //记录下一个单词的起始位置
                size = 0;
                while(s[i+1] == ' ') //删除中间多余空格
                    s.erase(s.begin()+i+1);
            }
        }
        reverse(s.begin()+flag,s.end());
        return s;
    }
};

5.4 182-动态口令

182

在这里插入图片描述

class Solution {
public: //1 2 3 4 5 6 7 -> 4 5 6 7 1 2 3
        //7 6 5 4 3 2 1 -> 7 6 5 4 1 2 3 -> 4 5 6 7 1 2 3
    string dynamicPassword(string password, int target) {
        int size = password.size();
        int newstart = size - target;
        reverse(password.begin(),password.end());
        reverse(password.begin(),password.begin()+newstart);
        reverse(password.begin()+newstart,password.end());
        return password;
    }
};

5.5* 459-重复的子字符串

459

在这里插入图片描述

class Solution {
public:
    bool repeatedSubstringPattern(string s) 
    {
        string tmp(s.begin(),s.end());
        tmp+=s;
        tmp.erase(tmp.begin());
        tmp.erase(tmp.end()-1);
        //删去头尾
        if(tmp.find(s) == string::npos)
            return false;
        //在tmp内寻找s,找到了就说明是重复组成的
        //abab ->(a)b abab a(b)
        //abcdabcd -> (a)bcd abcdabcd abc(d)
        return true;
    }
};

5.6* 28-找出字符串中第一个匹配项的下标(KMP)

28

在这里插入图片描述

class Solution {
public: 
    //aabaabaafa  aabaaf
    //前缀表的作用就是再两个字符串匹配失败时,能回到最近的匹配位置,记录能回到位置下标
    void getNext(int* next, const string& s) 
    {
        //-1 0  -1 0  1  -1
        //a  a  b  a  a  f
        int j = -1;
        next[0] = j;
        for(int i = 1; i < s.size(); i++) 
        { 
             //能进入就说明前面已经有重复的了
            //进不去说明和前面一样继续重复
            while (j >= 0 && s[i] != s[j + 1])  // 前后缀不相同了
                j = next[j]; // 向前回退

            if (s[i] == s[j + 1])  // 找到相同的前后缀
                j++;

            next[i] = j; // 将j(前缀的长度)赋给next[i]
        }
    }
    int strStr(string haystack, string needle) 
    {
        int size_ndl = needle.size();
        int size_hstk = haystack.size();

        int next[size_ndl];
        getNext(next, needle);
        int j = -1; // // 因为next数组里记录的起始位置为-1
        for (int i = 0; i < size_hstk; i++) 
        { 
            // 注意i就从0开始
            //当数据和前缀表有重合时且当下不对应
            //while放在if(匹配)前面,防止j一直++匹配成功后又进入循环判断下一个不匹配而重置j
            while(j >= 0 && haystack[i] != needle[j + 1])
                j = next[j]; // j 寻找之前匹配的位置 //重新加载前缀表

            if (haystack[i] == needle[j + 1])  // 匹配,j和i同时向后移动
                j++; // i的增加在for循环里
            
            if (j == (size_ndl - 1) )  // //当数据和前缀表完全重合
                return (i - size_ndl + 1);
        }
        return -1;
    }
};

6. 栈和队列篇

6.1 232-用栈实现队列

232

在这里插入图片描述

class MyQueue {
public:
    MyQueue() {

    }
    
    void push(int x) {
        s1.push(x);
    }
    
    int pop() {
        if(s2.empty()) //s2就相当于队列,s1存储数据,反转数据存入s2;
        {
            while(!s1.empty())
            {
                s2.push(s1.top());
                s1.pop();
            }
        }
        int ans = s2.top();
        s2.pop();
        return ans;
    }
    
    int peek() {
        int tmp = this->pop();
        s2.push(tmp);
        return tmp;
    }
    
    bool empty() {
        if(s1.empty() && s2.empty())
            return true;
        return false;
    }

private:
    stack<int> s1;
    stack<int> s2;
};

6.2 225-用队列实现栈

225

在这里插入图片描述

class MyStack {
public:
    MyStack() {

    }
    
    void push(int x) {
        if(!q1.empty())
            q1.push(x);
        else
            q2.push(x);
    }
    
    int pop() { //将其中一个队列中size-1个元素全部移入另一个队列,留下的元素pop
        int ans;
        if(!q1.empty()) //q1不为空,将元素移动到q2
        {
            while(q1.size() != 1)
            {
                q2.push(q1.front());
                q1.pop();
            }
            ans = q1.front();
            q1.pop();
        }
        else
        {
            while(q2.size() != 1)
            {
                q1.push(q2.front());
                q2.pop();
            }
            ans = q2.front();
            q2.pop();
        }
        return ans;
    }
    
    int top() {
        int tmp = this->pop();
        this->push(tmp);
        return tmp;
    }
    
    bool empty() {
        if(q1.empty() && q2.empty())
            return true;
        return false;
    }

private:
    queue<int> q1;
    queue<int> q2;
};

6.3 20-有效的括号

20

在这里插入图片描述

class Solution {
public://{([])}
    bool isValid(string s) {
        stack<char> st;
        for(char e : s)
        {
            if(e=='[' || e=='(' || e=='{') //左符号进入栈中
                st.push(e);
            else
            {
                if(st.empty())
                    return false;
                else if(e == ')' && st.top()=='(' 
                        || e == '}' && st.top() == '{' 
                        || e == ']' &&  st.top() == '[')
                    st.pop(); //找到对应的符号后删除左符号
                else
                    return false; //如果不符合这个规则,那么就不构成
            }
        }
        return st.empty(); //如果最后为空,则说明全部对应上了,否则即false
    }
};

6.4 1047-删除字符串中的所有相邻重复项

1047

在这里插入图片描述

class Solution {
public:
    string removeDuplicates(string s) {
        stack<int> st;
        for(char e : s)
        {
            if(st.empty() || e!=st.top())
                st.push(e);
            else
                st.pop();
        }
        //将栈中的正确答案转移至string类
        string ans;
        while(!st.empty())
        {
            ans+=st.top();
            st.pop();
        }
        //由于从栈中获取数据,因此答案要反转回来
        reverse(ans.begin(),ans.end());
        return ans;
    }
};

6.5 150-逆波兰表达式求值

150

在这里插入图片描述

class Solution {
public:
    int evalRPN(vector<string>& tokens) {
        stack<int> st;
        for(string& e : tokens)
        {
            if(e=="+" || e=="*" || e=="/" || e=="-")//如果为符号,则取栈顶两个数字进行运算
            {
                int second = st.top();
                st.pop();
                int first = st.top();
                st.pop();
                //取栈顶两个数据
                if(e=="+")
                    st.push(first+second);
                else if(e=="-")
                    st.push(first-second);
                else if(e=="*")
                    st.push(first*second);
                else if(e=="/")
                    st.push(first/second);
            }
            else //如果为数字则入栈
                st.push(stoi(e));
        }
        return st.top();
    }
};

6.6* 239-滑动窗口最大值(双端队列)

239

在这里插入图片描述

class Solution {
public:
    void push(int num)
    {
        while(!dq.empty() && dq.back() < num) //dq中第一个元素始终保证为最大值
            dq.pop_back(); 
        dq.push_back(num);
    }

    void pop(int num)
    {
        if(!dq.empty() && dq.front() == num)
            dq.pop_front();
    }

    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        vector<int> ans;
        //创建第一组滑动窗口
        for(int i = 0; i<k; ++i)
            push(nums[i]);
        ans.push_back(dq.front()); //放入第一组滑动窗口的最大值

        //开始处理后面的窗口
        int tmp = k;
        while(tmp < nums.size())
        {
            pop(nums[tmp-k]); //尝试删除dq中最大数字(滑动窗口滑过了这个数字,需要更新,因此删除)
            push(nums[tmp++]); //尝试更新
            ans.push_back(dq.front());
        }
        return ans;
    }

private:
    deque<int> dq; //双端队列
};

6.7* 347-前K个高频元素(优先级队列)

347

在这里插入图片描述

class Solution {
public:
    struct SecondCmp
    {
        bool operator()(const pair<int,int>& x,const pair<int,int>& y)
        {
            return x.second<y.second;
        }
    };

    vector<int> topKFrequent(vector<int>& nums, int k) {
        vector<int> ans;
        unordered_map<int,int> um; //key:元素 value:出现次数
        for(auto& e : nums)
            um[e]++;

        //使优先级队列升序排列,c++20适用
        //priority_queue<pair<int,int>,vector<pair<int,int>>,decltype([]
        //(const pair<int,int>& x,const pair<int,int>& y){
        //    return x.second<y.second;
        //})> pq;
        priority_queue<pair<int,int>,vector<pair<int,int>>,SecondCmp> pq;


        for(auto& e : um)
            pq.push(make_pair(e.first,e.second));
        
        while(k--)
        {
            ans.push_back(pq.top().first);
            pq.pop();
        }
        return ans;
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1047167.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[Realtek sdk-3.4.14b]RTL8197FH-VG 2.4G to WAN吞吐量低于60%的问题分析及解决方案

问题描述 RTL8197FH-VG 2.4G wifi to WAN吞吐量低于65%的标准,正常2T2R的wifi 300Mbps x 65% = 195Mbps,但是实际只能跑到160Mbps,这个时候CPU的idl已经为0,sirq占用率达到98%左右 网络拓扑 一台PC通过2.4G WiFi连接到RTL8197FH-VG,另外一台PC直接通过WAN口连接到RTL8197…

求各区域热门商品Top3 - HiveSQL

背景&#xff1a;这是尚硅谷SparkSQL练习题&#xff0c;本文用HiveSQL进行了实现。 数据集&#xff1a;用户点击表&#xff0c;商品表&#xff0c;城市表 题目: ① 求每个地区点击量前三的商品&#xff1b; ② 在①的基础上&#xff0c;求出每个地区点击量前三的商品后&a…

SkyWalking搭配springboot应用(三)

title: “SkyWalking搭配springboot应用(三)” createTime: 2021-07-13T16:27:5708:00 updateTime: 2021-07-13T16:27:5708:00 slug: “SkyWalking搭配springboot应用(三)” draft: false author: “ggball” tags: [“skywalking”] categories: [“java”] description: “sk…

重新认识mysql

title: “重新认识mysql” createTime: 2022-03-06T15:52:4108:00 updateTime: 2022-03-06T15:52:4108:00 draft: false author: “ggball” tags: [“mysql”] categories: [“db”] description: “” 文章目录 title: "重新认识mysql" createTime: 2022-03-06T15:…

路由器配置静态和默认路由实现VLAN之间的通信

目录 华为路由器静态路由和默认路由的写法 静态路由和默认路由的区别 案例 华为路由器静态路由和默认路由的写法 配置静态路由&#xff1a; [Huawei] ip route-static <目标网络> <子网掩码> <下一跳地址> 实例&#xff1a;将目标网络192.168.10.0/24的流…

UOS QTextEdit设置换行和滚动条(bug自动换行时右侧个别字符被遮盖)

一、环境 UOS_x86 / QT5 / C 二、qtextEdit 换行设置 下图在ui界面lineWrapMode这个参数可以设置换行相关&#xff1a;NoWrap是不换行、WidgetWidth是自动换行&#xff08;按textEdit的宽度换行&#xff09;、下面两个是可以自定义每行的宽度&#xff0c;如果选了这两个&…

Java8实战-总结37

Java8实战-总结37 默认方法不断演进的 API初始版本的 API第二版 API 默认方法 传统上&#xff0c;Java程序的接口是将相关方法按照约定组合到一起的方式。实现接口的类必须为接口中定义的每个方法提供一个实现&#xff0c;或者从父类中继承它的实现。但是&#xff0c;一旦类库…

【OSCAR开源产业大会分论坛】开源大模型走向何方?

再过俩月&#xff0c;ChatGPT 即将迎来推出一周年纪念日。作为开历史先河的 AI 大模型&#xff0c;ChatGPT 像一针猛戳进千行百业中枢神经的兴奋剂&#xff0c;在全球掀起空前绝后的 AI 军备竞赛热潮。 近一年来&#xff0c;我们看到 GPT-3.5 完成向多模态的 GPT-4 进化&#x…

为什么我的remix没有injected web3

原因 Remix近期做了升级&#xff0c;去除了Web3的选项&#xff0c;您在进行部署的时候&#xff0c;可以选择injected provider metamask&#xff0c;同样能连接到Web3钱包哦。具体如下图所示&#xff1a;

基于微信小程序的公交信息在线查询系统小程序设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言系统主要功能&#xff1a;具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计…

zemax西德莫尔目镜

高性能的军用光学仪器 在两个双胶合透镜之间&#xff0c;增加了一块平凸透镜 半视场角增大到35度 入瞳直径4mm波长0.51、0.56、0.61半视场35焦距27.9mm 镜头参数&#xff1a; 成像效果&#xff1a;

codesys【网桥】

作用&#xff1a;在串联的路由器上&#xff0c;实现PC2访问PC1 实现无线编程 和PLC【web】 1硬件连接&#xff1a; 2软件设置&#xff1a; 1网卡设置自动ip 2厂家软件连接到模块 串口服务器参数设置&#xff1a; (1)设置串口服务器软件版本为Z-Ver ATFVERz (2)使能以太网接口…

【AI视野·今日Robot 机器人论文速览 第四十期】Mon, 25 Sep 2023

AI视野今日CS.Robotics 机器人学论文速览 Mon, 25 Sep 2023 Totally 36 papers &#x1f449;上期速览✈更多精彩请移步主页 Interesting: &#x1f4da;CloudGripper, 一套云化的机器抓取人数据采集系统&#xff0c;包含了32个机械臂的集群。(from KTH Royal Institute of Te…

【Vue简介+搭建Vue开发环境+Hello小案例】

Vue简介搭建Vue开发环境Hello小案例 1 Vue简介2 搭建Vue开发环境3 Hello小案例 1 Vue简介 Vue是一套用于构建用户界面的渐进式JavaScript框架。&#xff08;渐进式&#xff1a;Vue可以自底向上逐层的应用<简单应用&#xff1a;只需要一个轻量小巧的核心库><复杂应用&…

2023年海南省职业院校技能大赛(高职组)信息安全管理与评估赛项规程

2023年海南省职业院校技能大赛&#xff08;高职组&#xff09; 信息安全管理与评估赛项规程 一、赛项名称 赛项名称&#xff1a;信息安全管理与评估 英文名称&#xff1a;Information Security Management and Evaluation 赛项组别&#xff1a;高等职业教育 赛项归属产业&…

解决java.io.FileNotFoundException: HADOOP_HOME and hadoop.home.dir are unset.的错误

文章目录 1. 复现错误2. 分析错误3. 解决问题3.1 下载Hadoop3.2 配置Hadoop3.3 下载winutils3.4 配置winutils 1. 复现错误 今天在运行同事给我的项目&#xff0c;但在项目启动时&#xff0c;报出如下错误&#xff1a; java.io.FileNotFoundException: java.io.FileNotFoundEx…

15.TIM输入捕获

目录 一、输入捕获 1.1 输入捕获简介 1.2输入捕获的各部分电路 ​编辑 1.3 输入捕获的主模式、从模式、触发源选择&#xff08;简称&#xff1a;主从触发模式&#xff09; ​编辑​编辑 ​编辑1.4 输入捕获和PWMI基本结构 二、频率的测量方法 2.1 测频法 2.2 …

新移科技发布基于联发科MT8390(Genio 700)平台的物联网 AI 核心板

新移科技研发的XY8390物联网 AI 核心板是一款高度集成、功能强大的平台&#xff0c;该核心板专为各种人工智能 (AI) 和物联网 (IoT) 用例而设计。 处理器采用了 Arm DynamIQ™ 技术&#xff0c;结合了高性能 Cortex-A78 内核和高能效 Cortex-A55 内核&#xff0c;并配备了 Arm …

【每日一题】528. 按权重随机选择

528. 按权重随机选择 - 力扣&#xff08;LeetCode&#xff09; 给你一个 下标从 0 开始 的正整数数组 w &#xff0c;其中 w[i] 代表第 i 个下标的权重。 请你实现一个函数 pickIndex &#xff0c;它可以 随机地 从范围 [0, w.length - 1] 内&#xff08;含 0 和 w.length - 1&…

康耐视visionpro脚本CogRectangleAffine ,CogPolygon图形限定框,边界显示(划痕缺陷案例分享)

目录 1.划痕缺陷整体方案设计:2.测试一效果图:3.测试一脚本编写​:4.测试二效果图:5.测试二脚本编写:6.测试三效果图:7.​测试三脚本编写:测试版本:康耐视visionpro9.0 1.划痕缺陷整体方案设计: 2.测试一效果图: 3.测试一脚本编写​: CogRectangleAffine Rectangle…