手把手帶你刷LeetCode-------愛學習的飼養員[c++版](數據結構篇)


數據結構1.數組 Array

LeetCode485.最大連續1的個數

給定一個二進制數組, 計算其中最大連續 1 的個數。

示例:

輸入:[1,1,0,1,1,1]
輸出:3
解釋:開頭的兩位和最后的三位都是連續 1 ,所以最大連續 1 的個數是 3.

class Solution {
public:
    int findMaxConsecutiveOnes(vector<int>& nums) {
        if(nums.size() == 0){
            return 0;
        }
        int count = 0,result = INT_MIN;
        for(int i = 0;i < nums.size();i++){
            if(nums[i] == 1){
                count++;
            }else{
                result = max(result,count);
                count = 0;
            }
        }
        return max(result,count);
    }
};

LeetCode283.移動零
給定一個數組 nums,編寫一個函數將所有 0 移動到數組的末尾,同時保持非零元素的相對順序。
示例:

輸入: [0,1,0,3,12]
輸出: [1,3,12,0,0]

class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int index = 0;
        for(int i = 0;i < nums.size();i++){
            if(nums[i] != 0){
                nums[index] = nums[i];
                index++;
            }
        }
        for(int i = index;i < nums.size();i++){
            nums[i] = 0;
        }
    }
};

LeetCode27.移除元素
給你一個數組 nums 和一個值 val,你需要 原地 移除所有數值等於 val 的元素,並返回移除后數組的新長度。
不要使用額外的數組空間,你必須僅使用 O(1) 額外空間並 原地 修改輸入數組。
元素的順序可以改變。你不需要考慮數組中超出新長度后面的元素。

示例 1:

輸入:nums = [3,2,2,3], val = 3
輸出:2, nums = [2,2]
解釋:函數應該返回新的長度 2, 並且 nums 中的前兩個元素均為 2。你不需要考慮數組中超出新長度后面的元素。例如,函數返回的新長度為 2 ,而 nums = [2,2,3,3] 或 nums = [2,2,0,0],也會被視作正確答案。

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

數據結構2.鏈表 linked list

LeetCode203.移除鏈表元素
給你一個鏈表的頭節點 head 和一個整數 val ,請你刪除鏈表中所有滿足 Node.val == val 的節點,並返回 新的頭節點 。
示例 1:
輸入:head = [1,2,6,3,4,5,6], val = 6
輸出:[1,2,3,4,5]

class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) 
    {
        ListNode *dummy = new ListNode;
        dummy -> next = head;
        ListNode *prev = dummy;
        while(head != NULL)
        {
            if(head -> val == val)
            {
                prev -> next = head -> next;
                head = head -> next;
            }
            else
            {
                prev = head;
                head = head -> next;
            }
        }
        return dummy -> next;
    }
};

LeetCode206.反轉鏈表
給你單鏈表的頭節點 head ,請你反轉鏈表,並返回反轉后的鏈表。
示例 1:
在這里插入圖片描述
輸入:head = [1,2,3,4,5]
輸出:[5,4,3,2,1]

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* dummy = new ListNode;
        dummy -> next = head;
        while(head != nullptr && head -> next != nullptr){
            ListNode* dnext = dummy -> next;
            ListNode* hnext = head -> next;
            dummy -> next = hnext;
            head -> next = hnext -> next;
            hnext -> next = dnext;
        }
        return dummy -> next;
    }
};

數據結構3.隊列 Queue

LeetCode933.最近的請求次數
寫一個 RecentCounter 類來計算特定時間范圍內最近的請求。
請你實現 RecentCounter 類:
RecentCounter() 初始化計數器,請求數為 0 。
int ping(int t) 在時間 t 添加一個新請求,其中 t 表示以毫秒為單位的某個時間,並返回過去 3000 毫秒內發生的所有請求數(包括新請求)。確切地說,返回在 [t-3000, t] 內發生的請求數。
保證 每次對 ping 的調用都使用比之前更大的 t 值。
示例:

輸入:
["RecentCounter", "ping", "ping", "ping", "ping"]
[[], [1], [100], [3001], [3002]]
輸出:
[null, 1, 2, 3, 3]

解釋:
RecentCounter recentCounter = new RecentCounter();
recentCounter.ping(1); // requests = [1],范圍是 [-2999,1],返回 1
recentCounter.ping(100); // requests = [1, 100],范圍是 [-2900,100],返回 2
recentCounter.ping(3001); // requests = [1, 100, 3001],范圍是 [1,3001],返回 3
recentCounter.ping(3002); // requests = [1, 100, 3001, 3002],范圍是 [2,3002],返回 3

class RecentCounter {
private:
    queue<int> q;
public:
    RecentCounter() {}
    
    int ping(int t) 
    {
        q.push(t);
        while(q.size() > 0 && t - q.front() > 3000)
        {
            q.pop();
        }
        return q.size();
    }
};

數據結構4.棧 stack

LeetCode20.有效的括號
給定一個只包括 '(',')','{','}','[',']' 的字符串 s ,判斷字符串是否有效。
有效字符串需滿足:
左括號必須用相同類型的右括號閉合。
左括號必須以正確的順序閉合。

示例 1:

輸入:s = "()"
輸出:true
示例 2:

輸入:s = "()[]{}"
輸出:true
示例 3:

輸入:s = "(]"
輸出:false
示例 4:

輸入:s = "([)]"
輸出:false
示例 5:

輸入:s = "{[]}"
輸出:true

class Solution {
public:
    bool isValid(string s) 
    {
        if(s.size() == 0)
            return true;
        stack<int> st;
        for(char c:s)
        {
            if(c == '(' || c == '[' || c == '{')
            { 
                st.push(c);
            }
            else
            {
                if(st.size() == 0)
                {
                    return false;
                }
                else
                {
                    int temp = st.top();
                    st.pop();
                    if(c == ')')
                    {
                        if(temp != '(')
                            return false;
                    }
                    else if(c == ']')
                    {
                        if(temp != '[')
                            return false;
                    }
                    else if(c == '}')
                    {
                        if(temp != '{')
                            return false;
                    }
                }
            }
        }
        if(st.size() == 0)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
};

LeetCode496.下一個更大的元素 I
給你兩個 沒有重復元素 的數組 nums1 和 nums2 ,其中nums1 是 nums2 的子集。
請你找出 nums1 中每個元素在 nums2 中的下一個比其大的值。
nums1 中數字 x 的下一個更大元素是指 x 在 nums2 中對應位置的右邊的第一個比 x 大的元素。如果不存在,對應位置輸出 -1 。

示例 1:
輸入: nums1 = [4,1,2], nums2 = [1,3,4,2].
輸出: [-1,3,-1]
解釋:
對於 num1 中的數字 4 ,你無法在第二個數組中找到下一個更大的數字,因此輸出 -1 。
對於 num1 中的數字 1 ,第二個數組中數字1右邊的下一個較大數字是 3 。
對於 num1 中的數字 2 ,第二個數組中沒有下一個更大的數字,因此輸出 -1 。

class Solution {
public:
    vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) 
    {
        vector<int> res;
        stack<int> st;
        for(int i = 0;i < nums2.size();i++)
        {
            st.push(nums2[i]);
        }
        for(int j = 0;j < nums1.size();j++)
        {
            stack<int> temp;
            bool isFound = false;
            int max = -1;
            while(st.size() != 0 && !isFound)
            {
                int top = st.top();
                st.pop();
                if(top > nums1[j])
                {
                    max = top;
                }
                else if(top == nums1[j])
                {
                    isFound = true;
                }
                temp.push(top);
            }
            res.push_back(max);
            while(temp.size() != 0)
            {
                st.push(temp.top());
                temp.pop();
            }
        }
        return res;
    }
};

數據結構5.哈希表 Hash Table

LeetCode217.存在重復元素
給定一個整數數組,判斷是否存在重復元素。
如果存在一值在數組中出現至少兩次,函數返回 true 。如果數組中每個元素都不相同,則返回 false 。

示例 1:
輸入: [1,2,3,1]
輸出: true

示例 2:
輸入: [1,2,3,4]
輸出: false

示例 3:
輸入: [1,1,1,3,3,4,3,2,4,2]
輸出: true

第一種利用哈希表:

class Solution {
public:
    bool containsDuplicate(vector<int>& nums) 
    {
        if(nums.size() == 0)
            return false;
        unordered_map<int,int> nhash;   //建立哈希表
        for(int i = 0;i < nums.size();i++)
        {
            if(nhash[nums[i]] == 0)     //如果從未在哈希表中出現則+1
            {
                nhash[nums[i]]++;
            }
            else                        //在哈希表出現過,證明重復直接返回true
            {
                return true;
            }
        }
        return false;
    }
};

第二種利用集合,利用了集合不能存儲重復數字的特性

class Solution {
public:
    bool containsDuplicate(vector<int>& nums) 
    {
        if(nums.size() == 0)
            return  false;
        unordered_set<int> nhash;
        for(int i = 0;i < nums.size();i++)
        {
            nhash.insert(nums[i]);      //添加到集合中
        }
        if(nhash.size() == nums.size())
        {
            return false;               //長度相等,證明不存在重復,返回false
        }
        else
        {
            return true;                //長度不等,存在重復,返回true
        }
    }
};

LeetCode389.找不同
給定兩個字符串 s 和 t,它們只包含小寫字母。

字符串 t 由字符串 s 隨機重排,然后在隨機位置添加一個字母。
請找出在 t 中被添加的字母。

示例 1:
輸入:s = "abcd", t = "abcde"
輸出:"e"
解釋:'e' 是那個被添加的字母。

示例 2:
輸入:s = "", t = "y"
輸出:"y"

class Solution {
public:
    char findTheDifference(string s, string t) {
        vector<int> hashtable(26,0);
        for(int i = 0;i < s.size();i++){
            hashtable[s[i] - 97]++;
        }
        for(int j = 0;j < t.size();j++){
            hashtable[t[j] - 97]--;
        }
        for(int k = 0;k < 26;k++){
            if(hashtable[k] != 0){
                return (char)(k + 'a');
            }
        }
        return ' ';
    }
};

數據結構6.集合 Set

LeetCode705.設計哈希表
不使用任何內建的哈希表庫設計一個哈希集合(HashSet)。

實現 MyHashSet 類:
void add(key) 向哈希集合中插入值 key 。
bool contains(key) 返回哈希集合中是否存在這個值 key 。
void remove(key) 將給定值 key 從哈希集合中刪除。如果哈希集合中沒有這個值,什么也不做。

示例:
輸入:
["MyHashSet", "add", "add", "contains", "contains", "add", "contains", "remove", "contains"]
[[], [1], [2], [1], [3], [2], [2], [2], [2]]
輸出:
[null, null, null, true, false, null, true, null, false]

解釋:
MyHashSet myHashSet = new MyHashSet();
myHashSet.add(1); // set = [1]
myHashSet.add(2); // set = [1, 2]
myHashSet.contains(1); // 返回 True
myHashSet.contains(3); // 返回 False ,(未找到)
myHashSet.add(2); // set = [1, 2]
myHashSet.contains(2); // 返回 True
myHashSet.remove(2); // set = [1]
myHashSet.contains(2); // 返回 False ,(已移除)

class MyHashSet {
public:
    vector<bool> nodes;
    /** Initialize your data structure here. */
    MyHashSet() {
        nodes.resize(1000001,false);
    }
    
    void add(int key) {
        nodes[key] = true;
    }
    
    void remove(int key) {
        nodes[key] = false;
    }
    
    /** Returns true if this set contains the specified element */
    bool contains(int key) {
        return nodes[key];
    }
};

數據結構7.樹 Tree

LeetCode144.二叉樹的前序遍歷
給你二叉樹的根節點 root ,返回它節點值的 前序 遍歷。
示例 1:
在這里插入圖片描述
輸入:root = [1,null,2,3]
輸出:[1,2,3]

class Solution {
public:
    void preorder(TreeNode* root,vector<int> &res)
    {
        if(root == nullptr)
            return;
        res.push_back(root -> val);
        preorder(root -> left,res);
        preorder(root -> right,res);
    }
    vector<int> preorderTraversal(TreeNode* root) 
    {
        vector<int> res;
        preorder(root,res);
        return res;
    }

數據結構8.堆 Heap

LeetCode215.數組中的第k個最大元素
在未排序的數組中找到第 k 個最大的元素。請注意,你需要找的是數組排序后的第 k 個最大的元素,而不是第 k 個不同的元素。

示例 1:
輸入: [3,2,1,5,6,4] 和 k = 2
輸出: 5

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        priority_queue<int,vector<int>,less<int>>q;
        for(int num:nums){
            q.push(num);
        }
        while(k > 1){
            q.pop();
            k--;
        }
        return q.top();
    }
};

LeetCode692.前K個高頻單詞
給一非空的單詞列表,返回前 k 個出現次數最多的單詞。
返回的答案應該按單詞出現頻率由高到低排序。如果不同的單詞有相同出現頻率,按字母順序排序。

示例 1:
輸入: ["i", "love", "leetcode", "i", "love", "coding"], k = 2
輸出: ["i", "love"]
解析: "i" 和 "love" 為出現次數最多的兩個單詞,均為2次。
注意,按字母順序 "i" 在 "love" 之前。

class cmp{
    public:
        bool operator()(const pair<string,int> &p1,const pair<string,int> &p2)
        {
            return p1.second == p2.second?(p1.first < p2.first):p1.second > p2.second;
        }
};
class Solution {
public:
    vector<string> topKFrequent(vector<string>& words, int k) {
        unordered_map<string,int> mapping;
        for(string word:words)
        {
            if(mapping.find(word) == mapping.end()){
                mapping.emplace(word,0);
            }
            int temp = mapping[word]++;
            mapping.emplace(word,temp);
        }
        priority_queue<pair<string,int>,vector<pair<string,int>>,cmp>minheap;
        for(auto it = mapping.begin();it != mapping.end();it++)
        {
            minheap.emplace(*it);
            if(minheap.size() > k)
            {
                minheap.pop();
            }
        }
        vector<string> result;
        while(!minheap.empty())
        {
            result.push_back(minheap.top().first);
            minheap.pop();
        }
        reverse(result.begin(),result.end());
        return result;
    }
};


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM