LeetCode 力扣 刷题记录 热题 HOT 100(206,207,208,215,221)题目+算法分析+Cpp解答

24 篇文章 0 订阅
17 篇文章 0 订阅
GitHub链接:https://github.com/WilliamWuLH/LeetCode
如果你觉得不错可以 ⭐Star 和 Fork ❤

206.Reverse Linked List

保存每一个链表结点:
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if(head == NULL)
            return NULL;
        vector<ListNode*> nodes;
        while(head != NULL){
            nodes.push_back(head);
            head = head->next;
        }
        for(int i=nodes.size()-1; i>0; i--){
            nodes[i]->next = nodes[i-1];
        }
        nodes[0]->next = NULL;
        return nodes[nodes.size()-1];
    }
};
双指针:
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* per = NULL;
        ListNode* cur = head;
        while(cur != NULL){
            ListNode* temp = cur->next;
            cur->next = per;
            per = cur;
            cur = temp;
        }
        return per;
    }
};

207.Course Schedule

宽度优先搜索 BFS 实现拓扑排序:

​ 首先把边缘列表表示的图转为邻接表表示的图。

​ 然后找出所有入度为 0 的结点,插入队列中,入度为 0 即表示此时没有前导课程的结点。

​ 判断队列不为空时,取出队首元素,找到它可以到达的结点,将这些结点的入度都减去 1 并去掉此时取出的队首元素,表示这个课程已经学过了讨论过了,可以进入下一门课程,此时学过的课程数目要加一。

​ 在讨论队列中每一个元素的同时需要判断此时哪些结点的入度为 0,将入度为 0 的结点添加到队列中。

​ 最后判断学过的课程数目是否等于总课程数目,以此来得到答案。

​ 以上的这个过程其实就是判断图是否是有向无环图 DAG (Directed acyclic graph)的过程。

​ 如果图中存在环,则成环的结点的入度将永远不为 0,那么这些结点将永远进不了队列,这些课程将永远无法学习,最终的学过的课程数目将少于总的课程数目。

​ 如果图是有向无环图 DAG,则图中不存在环,每个结点经过计算最后的入度都会变为 0,最终学过的课程数目将等于总的课程数目。

class Solution {
public:
    bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
        int count = 0;
        int before[numCourses];
        memset(before, 0, numCourses*sizeof(int));
        vector<vector<int>> graph(numCourses);
        vector<vector<int>>::iterator it;
        for(it = prerequisites.begin(); it != prerequisites.end(); it++){
            graph[ (*it)[0] ].push_back( (*it)[1] );
            before[ (*it)[1] ]++;
        }
        queue<int> q;
        for(int i=0; i<numCourses; i++)
            if(before[i] == 0)
                q.push(i);
        while(!q.empty()){
            int course = q.front();
            q.pop();
            count++;
            vector<int>::iterator i;
            for(i = graph[course].begin(); i != graph[course].end(); i++){
                before[*i]--;
                if(before[*i] == 0)
                    q.push(*i);
            }
        }
        return count == numCourses;
    }
};

208.Implement Trie (Prefix Tree)

Trie 前缀树:

​ 由于所有的输入都是由小写字母 a-z 构成的,所以我干脆一个树结点定义有26个孩子结点。

​ 树结点的 end 变量表示一个 word 在这个结点结束,方便进行 search 判断。

class Trie {
private:
    struct ListNode{
        int end;
        ListNode * child[26];
    };
    ListNode * head = NULL;
public:
    /** Initialize your data structure here. */
    Trie() {
        head = new ListNode;
        for(int k=0; k<26; k++)
            head->child[k] = NULL;
    }
    
    /** Inserts a word into the trie. */
    void insert(string word) {
        int len = word.length();
        ListNode * index = head;
        for(int i=0; i<len; i++){
            int pos = word[i] - 'a';
            if(index->child[pos] == NULL){
                index->child[pos] = new ListNode;
                for(int k=0; k<26; k++)
                    index->child[pos]->child[k] = NULL;
            }
            index = index->child[pos];
        }
        index->end = 1;
    }
    
    /** Returns if the word is in the trie. */
    bool search(string word) {
        int len = word.length();
        ListNode * index = head;
        for(int i=0; i<len; i++){
            int pos = word[i] - 'a';
            if(index->child[pos] == NULL)
                return false;
            index = index->child[pos];
        }
        if(index->end == 1)
            return true;
        return false;
    }
    
    /** Returns if there is any word in the trie that starts with the given prefix. */
    bool startsWith(string prefix) {
        int len = prefix.length();
        ListNode * index = head;
        for(int i=0; i<len; i++){
            int pos = prefix[i] - 'a';
            if(index->child[pos] == NULL)
                return false;
            index = index->child[pos];
        }
        return true;
    }
};

/**
 * Your Trie object will be instantiated and called as such:
 * Trie* obj = new Trie();
 * obj->insert(word);
 * bool param_2 = obj->search(word);
 * bool param_3 = obj->startsWith(prefix);
 */

215.Kth Largest Element in an Array

直接 sort:
class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        sort(nums.begin(), nums.end());
        return *(nums.end()-k);
    }
};
堆排序:
class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        return heapsort(nums, k);
    }
    void buildheap(vector<int>& nums,int root, int len){
        int child = root*2+1;
        if(child >= len)
            return;
        if(child+1 < len && nums[child+1] > nums[child])
            child++;
        if(nums[root] >= nums[child] )
            return;
        else{
            swap(nums[root], nums[child]);
            buildheap(nums, child, len);
        }
        return;
    }
    int heapsort(vector<int>& nums, int k){
        int len = nums.size();
        for(int i=len/2-1; i>=0; i--)
            buildheap(nums, i, len);
        for(int i=1; i<=k; i++){
            swap(nums[0], nums[len-i]);
            buildheap(nums, 0, len-i);
        }
        return nums[len-k];
    }
};

221.Maximal Square

确定正方形的左上角,逐层判断其边界是否满足条件:
class Solution {
public:
    int maximalSquare(vector<vector<char>>& matrix) {
        int ans = 0;
        for(int i=0; i<matrix.size()-ans; i++){
            for(int j=0; j<matrix[i].size()-ans; j++){
                if(matrix[i][j] == '0')
                    continue;
                ans = max(ans, 1);
                int len = 1,flag = 1;
                while(flag){
                    if(i+len >= matrix.size() || j+len >= matrix[i].size() )
                        break;
                    for(int k=0; k<=len; k++){
                        if(matrix[i+len][j+k] == '0' || matrix[i+k][j+len] == '0'){
                            flag = 0;
                            break;
                        }
                    }
                    if(flag){
                        ans = max(ans, len+1);
                        len++;
                    }
                }
            }
        }
        return ans*ans;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值