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

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 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>& prerequisites) {
        int count = 0;
        int before[numCourses];
        memset(before, 0, numCourses*sizeof(int));
        vector> graph(numCourses);
        vector>::iterator it;
        for(it = prerequisites.begin(); it != prerequisites.end(); it++){
            graph[ (*it)[0] ].push_back( (*it)[1] );
            before[ (*it)[1] ]++;
        }
        queue q;
        for(int i=0; i::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; ichild[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; ichild[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; ichild[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& nums, int k) {
        sort(nums.begin(), nums.end());
        return *(nums.end()-k);
    }
};

堆排序:

class Solution {
public:
    int findKthLargest(vector& nums, int k) {
        return heapsort(nums, k);
    }
    void buildheap(vector& 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& 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>& matrix) {
        int ans = 0;
        for(int i=0; i= 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;
    }
};

你可能感兴趣的:(算法,LeetCode,C++)