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;
}
};