在leetcode刷了点题,我觉得题解太杂而且我也是鶸,所以把我的思路po出来了
目录
1.括号匹配(简单匹配)
力扣https://leetcode-cn.com/problems/valid-parentheses/思路其实非常简单,就是利用堆栈,每一次新的元素与上一次堆入栈中的元素进行匹配,如果匹配成功即弹出栈,最后栈空了说明就是全部括号匹配成功!
class Solution {
public:
bool isValid(string s) {
int length=s.length();
stack<char> st;
st.push(s[0]);
for(int i=1;i<length;i++){
if(st.empty()){
st.push(s[i]);
continue;
}
char temp=st.top();
if(temp=='['&&s[i]==']')
{
st.pop();
continue;
}
else if(temp=='{'&&s[i]=='}'){
st.pop();
continue;
}
else if(temp=='('&&s[i]==')')
{
st.pop();
continue;
}
else{
st.push(s[i]);
}
}
if(st.empty()){
return 1;
}
else{
return 0;
}
}
};
2.栈模拟队列(利用两个栈即可)
力扣https://leetcode-cn.com/problems/implement-queue-using-stacks/我这种做法很好理解但是不高效;
class MyQueue {
public:
stack<int> s1;//主
stack<int> s2;//辅
MyQueue() {
}
void push(int x) {
s1.push(x);
}
int pop() {
while(!s1.empty()){
s2.push(s1.top());
s1.pop();
}
int temp=s2.top();
s2.pop();
while(!s2.empty()){
s1.push(s2.top());
s2.pop();
}
return temp;
}
int peek() {
while(!s1.empty()){
s2.push(s1.top());
s1.pop();
}
int temp=s2.top();
while(!s2.empty()){
s1.push(s2.top());
s2.pop();
}
return temp;
}
bool empty() {
if(s1.empty()){
return 1;
}
else
return 0;
}
};
/**
* Your MyQueue object will be instantiated and called as such:
* MyQueue* obj = new MyQueue();
* obj->push(x);
* int param_2 = obj->pop();
* int param_3 = obj->peek();
* bool param_4 = obj->empty();
*/
其实更简便的方法只是把两个栈只需判断其中一个是否非空就可以直接出结果的(if----else)
3.二叉树前中后序遍历
递归遍历老模板了 (注意里面的引用,返回vector)
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> temp;
traversalTree(root,temp);
return temp;
}
void traversalTree(TreeNode* root, vector<int> &s){
if(root==NULL)
return ;
s.push_back(root->val);
traversalTree(root->left,s);
traversalTree(root->right,s);
}
};
4.环形链表
题目
题解
其实可以想一下初中学的追赶问题,跑到快的总会追上跑的慢的同学;
5.合并两个有序链表
递归我是没想到的。。。。,又简洁明了,犇。
力扣https://leetcode-cn.com/problems/merge-two-sorted-lists/
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
if(l1==NULL)
return l2;
if(l2==NULL)
return l1;
if(l1->val < l2->val){
l1->next = mergeTwoLists(l1->next,l2);
return l1;
}else{
l2->next = mergeTwoLists(l1,l2->next);
return l2;
}
}
};
6.计算二叉树某节点的层次(由先序遍历可知)
(14条消息) 计算二叉树中指定结点所在的层次_奋斗的女孩儿-CSDN博客
其实可以总结一个通用计算层次的模板
代码里面,L非常重要,因为随着先序的节点遍历,先序遍历同一层时,由于递归的作用,如果说把L设为static,而不设为传到递归的下一层的值,会导致第三层的某个节点的层次错误地变成大于三的值;若进行传值调用,L在遍历同一层的时候层次数不会变。
void level(BiTree* T,int L,int *t)//这里面的t是通过指针调用
{
if(T)
{
L++;// L非常重要,因为随着节点的遍历,L在遍历同一层的时候不会变。
if(T->data==e)
{
*t=L;
}
level(T->lchild,L,t);
level(T->rchild,L,t);
}
}
巧了,关于这题恰好leetcode有一题(难度大一点)
993. 二叉树的堂兄弟节点 - 力扣(LeetCode) (leetcode-cn.com)
题解
(14条消息) 力扣993 二叉树堂兄弟节点 递归+DFS_小吕的博客-CSDN博客_力扣 树节点
在上面的题解中,其实先遍历左子树或者遍历右子树都是一样的!
class Solution {
public:
int xdepth=-1;
int ydepth=-1;
TreeNode* xparent;
TreeNode* yparent;
void dfs(TreeNode* root,int x,int y, int depth)
{
if(xdepth!=-1&&ydepth!=-1) return;
if(root->right!=nullptr)
{
if(root->right->val==x)
{
xdepth=depth;
xparent=root;
}
if(root->right->val==y)
{
ydepth=depth;
yparent=root;
}
dfs(root->right,x,y,depth+1);
}
if(root->left!=nullptr)
{
if(root->left->val==x)
{
xdepth=depth;
xparent=root;
}
if(root->left->val==y)
{
ydepth=depth;
yparent=root;
}
dfs(root->left,x,y,depth+1);
}
return;
}
bool isCousins(TreeNode* root, int x, int y) {
if(root==nullptr) return false;
dfs(root,x,y,0);
if((xparent!=yparent)&&(xdepth==ydepth))
return true;
else return false;
}
};
7.输出倒数第k个节点后序
递归,记得用void进行递归比较好理解,因为用主函数ListNode递归会找不到怎么返回节点的方式,因为我们是用链表的逆序,所以用下面方式比较好
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
int count = 0;
ListNode *node;
ListNode * getKthFromEnd(ListNode *head, int k) {
func(head,k);
return node;
}
void func(ListNode *head,int k){
if (head == NULL){
return;
}
func(head->next,k);
count++;
if (count == k){
node = head;
}
}
};
我发现一个赖皮的做法(真香)
class Solution {
public:
ListNode* getKthFromEnd(ListNode* head, int k) {
vector<ListNode*> res;
while(head!=NULL)
{
res.push_back(head);
head=head->next;
}
return res[res.size()-k];
}
};