文章目录
- 引言
- 新作
- 括号生成
- 个人实现
- 实现时遇到的问题
- 实现代码
 
- 参考思路
- 实现代码
 
 
- 合并K个有序链表
- 个人实现
- 实现代码
 
 
- 参考实现
- 实现代码
 
 
 
- 总结
 
引言
- 今天把第二篇论文投了,后续有审稿意见再说,然后在进行修改的。
- 后续的生活要步入正轨了,每天刷题,然后再背八股。
新作
括号生成
- 题目链接
  
个人实现
- 之前做过一个题目,是验证括号是否合法,这道题是让生成括号。可以在暴力的基础上,进行括号合法性的验证。最终的思路如下
- 有两种情况,验证括号的栈是否为空 
  - 如果栈为空, 
    - 还可以入栈,那就入栈
- 所有括号已经匹配完毕,为空,将结果加入到res中
 
- 如果栈不为空 
    - 入栈
- 出栈
 
 
- 如果栈为空, 
    
- 想的挺好的,但是实现起来比较困难,没有啥头绪,所以采用了最直接的方法进行暴力遍历所有的组合,然后判定是否符合要求,符合要求再添加对应的元素。时间复杂度是真的高 ,好在数据量并不多。
实现时遇到的问题
- 排列组合应该怎么用代码实现,想了半天,写的有点不熟,自己一点点理出来的,应该好好记住才对。 
  - 这里是使用dfs实现组合的。
 
实现代码

实现代码
#include <iostream>
#include <stack>
#include <vector>
using namespace std;
bool judge(string s){
    stack<char> st;
    for (auto c:s) {
        if (c == '(')   st.push(c);
        else{
            if (st.empty()) return false;
            else    st.pop();
        }
    }
    return st.empty();
}
vector<string> vt;
void dfs(string s,int t,int k){
    if (t == k){
        vt.push_back(s);
    }else{
        dfs(s + "(",t + 1,k);
        dfs(s + ")",t + 1,k);
    }
}
vector<string> generateParenthesis(int n){
    vector<string> res;
    dfs("",0,2*n);
    for (auto t:vt) {
        if (judge(t))   res.push_back(t);
    }
    return res;
}
int main(){
}
参考思路
下面这个是个好东西,经常用,需要呗
-  一个合法的括号序列的充分必要条件 - 任意前缀中,左括号的数量,大于等于右括号数量
- 左右括号数量相等
 
-  所以,第二个条件已经满足了,所以需要需要针对第一个条件进行计算 
-  使用递归来实现将所有合法方案输出的情况 - 任何情况,都可以填左括号
- 什么时候填右括号 
    - 满足数量要求
- 前缀的左括号数量的大于等于右括号
 
 
-  定理:卡特兰数 
实现代码
太牛逼了,这个代码写的真丝滑!!
vector<string> res;
void dfs(int n,int lc,int rc,string s){
    /*
     * n表示括号数量,lc表示左括号数量,rc表示右括号数量,s表示字符串
     */
    // 判定什么时候加左括号
    if (lc == n && rc == n) res.push_back(s); 
    else{
        // 什么时候加右括号
        if (lc < n) dfs(n,lc + 1,rc,s + "(");
        if (lc > rc && rc < n) dfs(n,lc,rc + 1,s + ")");
    }
}
vector<string> generateParenthesis(int n){
    dfs(n,0,0,"");
    return res;
}
实现过程中,有如下问题
- 注意,实现判断的是否相等,不相等再加括号,相等了就不加括号
- 如果加括号,再继续往下处理。
合并K个有序链表
- 题目链接
  
个人实现
- 将所有的链表合成一个新的有序链表,有以下两个特征 
  - 有序链表
- 多个合成一个
 
- 之前做过两个有序链表合成一个有序链表,用的两个指针同时比较,选择一个最小的然后进行链接。
- 如果采用同样的方法,计算复杂度有点高,有什么别的办法吗?如果不行,就只能暴力了。
- 最多是500个子队列,然后要维护500个指针。这个方法是不得行的。
- 跳过,这个不会做。
还有什么思路
 维系一个最值的队列
- 计算每一个链表的最大值和最小值,然后比较对应的最值,根据最值进行链接。
如果最值就是数次链接,这道题只能这样遍历
实现代码
暴力匹配
- 编程的具体实现就是,两两匹配,然后将第三者元素加入其中。将问题拆解。
- 具体实现如下,头一次跑通了一个hard的题目,心情很不错,向这种拆解问题的思想,真的很好用呀!
/**
 * 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:
   
ListNode* mergeKLists(vector<ListNode*>& lists) {
    auto dummy = new ListNode(-1);
    auto temp = dummy;
    for (auto t:lists) {
        temp->next = mergeTwoLists(temp->next,t);
        return dummy->next;
    }
    return dummy->next;
}
 ListNode* mergeTwoLists(ListNode* aNode,ListNode* bNode){
    auto dummy = new ListNode(-1);
    auto temp = dummy;
    while(aNode && bNode){
        if (aNode->val < bNode->val){
            temp->next = aNode;
            aNode = aNode->next;
        }else{
            temp->next = bNode;
            bNode = bNode->next;
        }
        temp = temp->next;
    }
    temp->next = aNode == nullptr ? bNode:aNode;
    return dummy->next;
}
};

参考实现
-  使用堆来找最小值,改变时间复杂度有k变成logk 
-  stl中的优先队列是使用堆进行排序的,所以这里使用优先队列进行实现。 - 这里自定义优先队里的比较函数比较生僻,需要死记硬背
 
定义一个保存ListNode 的优先队列
- 这个必须要记住,而且必须加上对应的容器
struct Cmp{
    bool operator()(ListNode* a,ListNode* b){
        return a->val > b->val;
    }
};
ListNode* mergeKLists(vector<ListNode*>& lists) {
   priority_queue<ListNode* ,vector<ListNode*>,Cmp> heap;
}
实现代码
- 下面这个题写的真简洁,学到了。
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
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) {}
};
struct Cmp{
    bool operator()(ListNode* a,ListNode* b){
        return a->val > b->val;
    }
};
ListNode* mergeKLists(vector<ListNode*>& lists) {
   priority_queue<ListNode* ,vector<ListNode*>,Cmp> heap;
   auto dummy = new ListNode(-1),tail = dummy;
   for (auto t:lists)  if(t) heap.push(t);
   while(heap.size()){
       auto t = heap.top();
       heap.pop();
       tail->next = t;
       tail = tail->next;
       if (t->next) heap.push(t->next);
   }
   
   return dummy->next;
}
总结
- 今天两道题基本上都写出来,但是效率都不高,学到了新的知识点,不错,明天继续。



















