1--有效的括号(20)
主要思路:
利用栈,遍历字符串,遇到左括号则入栈,遇到右括号则出栈,并判断出栈元素是否与右括号匹配;
当字符串有效时,栈为空(所有左括号都匹配出栈);当字符串无效时,则栈不为空(仍有未匹配的左括号);
#include <iostream>
#include <string>
#include <stack>class Solution {
public:bool isValid(std::string s) {int len = s.length();if (len == 0) return true;for(int i = 0; i < len; i++){if (s[i] == '(' || s[i] == '{' || s[i] == '['){st.push(s[i]);} else if(s[i] == ')' && !st.empty()){char c = st.top();st.pop();if (c != '(') return false;}else if(s[i] == '}' && !st.empty()){char c = st.top();st.pop();if (c != '{') return false;}else if(s[i] == ']' && !st.empty()){char c = st.top();st.pop();if (c != '[') return false;}elsereturn false;}return st.empty();}
private:std::stack<char> st;
};int main(int argc, char *argv[]){std::string test = "()[]{}";Solution S1;bool res = S1.isValid(test);if(res) std::cout << "true" << std::endl;else std::cout << "false" << std::endl;return 0;
}
2--合并两个有序链表(21)
主要思路:
归并排序,分别遍历比较两个链表的结点,数值小的结点归并到新链表中;
#include <iostream>
#include <string>
#include <stack>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* mergeTwoLists(ListNode* list1, ListNode* list2) {if(list1 == NULL && list2 == NULL) return NULL;ListNode* head = new ListNode();ListNode* l_back = head; // 指向新链表最后一个结点ListNode* l1 = list1;ListNode* l2 = list2;while(l1 != NULL && l2 != NULL){if(l1->val < l2->val){l_back->next = l1;l1 = l1->next;l_back = l_back->next;}else{l_back->next = l2;l2 = l2->next;l_back = l_back->next;}}if(l1 == NULL) l_back->next = l2;if(l2 == NULL) l_back->next = l1;return head->next;}
};int main(int argc, char *argv[]){ListNode* Node1 = new ListNode(1);ListNode* Node2 = new ListNode(2);ListNode* Node3 = new ListNode(4);Node1->next = Node2;Node2->next = Node3;ListNode* Node4 = new ListNode(1);ListNode* Node5 = new ListNode(3);ListNode* Node6 = new ListNode(4);Node4->next = Node5;Node5->next = Node6;Solution S1;ListNode* l = S1.mergeTwoLists(Node1, Node4);while(l != NULL){std::cout << l->val << " ";l = l->next;} return 0;
}
3--括号生成(22)
主要思路:视频讲解
递归遍历第 num 个字符是属于左括号还是右括号,递归终止条件是剩下的左括号和右括号数为 0;
有效的括号组合必须是当前剩下的右括号数必须大于剩下的左括号数;
#include <iostream>
#include <string>
#include <vector>class Solution {
public:std::vector<std::string> generateParenthesis(int n) {recur(n, n, 0);return Res;}// 还剩下 left 个和 right 个左括号和右括号,当前要填第 num 个字符void recur(int left, int right, int num){if(left == 0 && right == 0){c[num] = 0;Res.push_back(c);return;}if(left){ // 剩下的左括号不为 0c[num] = '(';recur(left - 1, right, num + 1);}if(left < right){ // 剩下的右括号必须大于剩下的左括号c[num] = ')';recur(left, right - 1, num + 1);}}
private:std::vector<std::string> Res;char c[20];
};int main(int argc, char *argv[]){int n = 3;Solution S1;std::vector<std::string> Res = S1.generateParenthesis(n);for(std::string value : Res){std::cout << value << std::endl;}return 0;
}
4--合并K个升序链表(23)
主要思路:视频讲解参考
与归并排序两个有序链表的思想类似,可以用 k 个结点指针指向 k 个链表的结点,每次归并值最小的结点到链表中,同时结点下移;
为了方便比较 k 个链表结点的值大小,可以用一个集合来存储和维护 k 个链表结点,其中这个集合默认以升序排列;则每次只需要取集合的头元素出来即可,并将该元素的下一个结点重新存储在 k 个链表结点中;
#include <iostream>
#include <queue>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(std::vector<ListNode*>& lists) {using Elem = std::pair<int, ListNode*>;// 定义一个堆,用于存储 k 个头结点(升序排列)std::priority_queue<Elem, std::vector<Elem>, std::greater<Elem>> Stack;// 用 k 个链表的头结点初始化堆for(ListNode* item : lists) if(item){Stack.push({item->val, item});}// 定义归并后的链表ListNode *head = nullptr;ListNode *tail = nullptr;while(!Stack.empty()){Elem tmp = Stack.top();Stack.pop();if(head == nullptr){head = tail = tmp.second; // 空链表时第一个结点作为头节点}else{tail->next = tmp.second; // 链表非空,将新结点加入到链表尾部tail = tail->next; // 更新尾指针}if(tmp.second->next != nullptr){ // 将下一个结点放到堆中,用于下一轮的比较Stack.push({tmp.second->next->val, tmp.second->next});}}return head;}};int main(int argc, char *argv[]){ListNode *Node1 = new ListNode(1);ListNode *Node2 = new ListNode(4);ListNode *Node3 = new ListNode(5);Node1->next = Node2;Node2->next = Node3;ListNode *Node4 = new ListNode(1);ListNode *Node5 = new ListNode(3);ListNode *Node6 = new ListNode(4);Node4->next = Node5;Node5->next = Node6;ListNode *Node7 = new ListNode(2);ListNode *Node8 = new ListNode(6);Node7->next = Node8;std::vector<ListNode*> Lists = {Node1, Node4, Node7};Solution S1;ListNode *NewList = S1.mergeKLists(Lists);while(NewList != nullptr){std::cout << NewList->val << " ";NewList = NewList->next;}return 0;
}
5--下一个排列(31)
主要思路: