数据结构1:队列与栈

向YZT学习。
立志每天刷一道题,提高自己编程实现想法、解决问题的能力,将idea变成code。
注:鉴于本人水平非常有限,以下贴文仅做笔记参考。如有谬误,敬请斧正。

1.队列

1.1知识点

  1. 队列是先入先出,栈后入先出。
  2. 循环队列的写法;leetcode上收藏了一个十分经典的循环队列写法。注意该设计末尾指针tail指向空位,并不指向最后一个元素,与STL模板库风格相同。
  3. 广度优先搜索BFS搜索最短路径

1.2 笔记

vector可以通过resize和assign来设置容量。

广度优先搜索模板;

vector<vector<int>> levelOrder(TreeNode* root) {
    queue<TreeNode*> q;
    q.push(root);
    //...
    while(q.size())
    {
        int size=q.size();
        //...
        for(int i=0;i<size;i++)
        {
            TreeNode* rt=q.front();q.pop();
            //...
            if(rt->left) q.push(rt->left);
            if(rt->right) q.push(rt->right);
        }
    }
    //return ...
}

1.3 岛屿数量

真的是被虐了。推荐一位大神,刷了700道leetcode。
BFS之岛屿数量
这种题目还是挺难的,刚看了答案,先记录这道题的解法,明日自己动手写。

  • 以第一个为1的点作为种子点,使用BFS进行搜索;具体内容为标记该位置为陆地,并以该点向四周扩展,如果为陆地,则加入队列;随后以队列中的每个元素作为种子点,重复以上过程,知道队列里所有点均被查找完,表示以该种子点延伸出的整块岛屿的陆地均被标记了。即发现了一块完整的大岛屿,岛屿数加1。
  • 重复以上过程,直到所有的点均被遍历。
// 此处添加岛屿数量BFS搜索代码
class Solution {
public:
    int numIslands(vector<vector<char>>& grid) {
        int rows = grid.size();
        int cols = grid[0].size();
        if(rows==0 || cols==0) return 0;
        
        // 遍历所有点
        int count = 0;
        for(int i=0;i<rows;i++)
        {
            for(int j=0;j<cols;j++)
            {
                if(grid[i][j]=='1')
                {
                    grid[i][j]='X';
                    bfs(grid,i,j);
                    count++;
                }
            }          
        }
        return count;      
    }
    
    void bfs(vector<vector<char> >& grid,int row,int col){
        int height = grid.size();
        int width = grid[0].size();

        queue<int> q;
        q.push(row);
        q.push(col);
           
        while(!q.empty()){
            int curr_row = q.front();
            q.pop();
            int curr_col = q.front();
            q.pop();
            // 向上扩展
            if(curr_row-1>=0 && grid[curr_row-1][curr_col]=='1'){
                grid[curr_row-1][curr_col]='X';
                q.push(curr_row-1);
                q.push(curr_col);
            }  
            
            // 向左扩展
            if(curr_col-1>=0 && grid[curr_row][curr_col-1]=='1'){
                grid[curr_row][curr_col-1]='X';
                q.push(curr_row);
                q.push(curr_col-1);
            }

            // 向右扩展
            if(curr_col+1<width && grid[curr_row][curr_col+1]=='1'){
                grid[curr_row][curr_col+1]='X';
                q.push(curr_row);
                q.push(curr_col+1);
            }

            // 向下扩展
            if(curr_row+1<height && grid[curr_row+1][curr_col]=='1'){
                grid[curr_row+1][curr_col]='X';
                q.push(curr_row+1);
                q.push(curr_col);
            }    
        }
    }
    
};

花了点时间写了一下,感觉其实挺简单的。总结一下就是以某个位置上周边一圈一圈扩展,把最邻近的满足条件的值入队,并标记已经找过的位置,随后重复直到找不到无法满足条件的值,即以某种子节点的BFS搜索结束。
注意:以上代码会报错。
问题在于一开始行与列的判断,请参考&&判断问题
下面这样先后判断才是对的,否则会报错。

        int rows = grid.size();
        if(rows<1) return 0;
        int cols = grid[0].size();
        if(cols<1) return 0;

1.4 转盘锁

题目不抄了。
我太菜了,写点思路。

  1. 当前位置与目标的距离,并判断哪些转轮需要拨动

1.5 完全平方数

写点思路:应该要找到floor(sqrt(n)),然后以该值为种子点,进行判断…设计好难。

一般解法:


// 1-初始化
int diff;
vector<int> vComp;
vComp.push_back(getMaxC(n,diff) );


//2-求diff的最大分量
while( getMaxC(diff)!=0 ){
	vComp.push_back(getMaxC(diff,diff) );//分量数组
	//diff =diff-getMaxC(diff)*getMaxC(diff);
}


// 计算一个数的最大分量和差
int getMaxC(int n,int &diff){
    if(n<1) return 0;
    int maxC = 1;
    while(maxC*maxC <= n ){
        maxC++;
    }
     diff = n-(maxC-1)*(maxC-1);
    return maxC-1;
}

注意:以上解法错误。从最大平方因子进行分解并不一定能取得最少的因子个数,比如12=3*3+1+1+1此时4项,而3*4仅有3项。还是得BFS
BFS正解如下:

2.栈

2.0 深度优先搜索

class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        vector<vector<int>> res;
        dfs(root,res,0);
        return res;
    }
    void dfs(TreeNode* root,vector<vector<int>>& res,int level)
    {
        if(!root) return;
        if(level>=res.size()) res.emplace_back(vector<int>());
        res[level].emplace_back(root->val);
        dfs(root->left,res,level+1);
        dfs(root->right,res,level+1);
    }
};

2.1 最小栈

没用过stack,一脸懵逼。上网搜了一下答案,单个栈是没法儿实现求解最小元素的,必须借助额外空间,以空间复杂度换取时间复杂度。借助辅助栈就可完成,下午写一下。
注意:栈是空的时候入栈这个条件。

class MinStack {
    stack<int> mStack;
    stack<int> minStack;
    
public:
    /** initialize your data structure here. */
    MinStack() {

    }
    
    void push(int x) {
        mStack.push(x);
        if(minStack.empty() || x<=minStack.top()){
            minStack.push(x);
        }else minStack.push(minStack.top());
    }
    
    void pop() {
        if(mStack.empty()){
            noexcept("no");
        }else{
            mStack.pop();
            minStack.pop();
        }
    }
    
    int top() {
        return mStack.top();
    }
    
    int getMin() {
        if(mStack.empty()){
            //noexcept("no");
            throw out_of_range("The stack is empty, please check!\n");
        }else return minStack.top();
    }
};

/**
 * Your MinStack object will be instantiated and called as such:
 * MinStack* obj = new MinStack();
 * obj->push(x);
 * obj->pop();
 * int param_3 = obj->top();
 * int param_4 = obj->getMin();
 */

2.2 有效括号

这个比较简单,自己花了会儿时间,调一调,就写好了。以下为原创解法。
1-特别判断 size=0或者1
2-依次查找该字符串,如果是左括号则入栈;如果第一个遇到右括号则返回;
3-否则判断当前右括号与左括号顶端是否成对,不成对则返回false;
4-成对则将当前左括号栈栈顶弹出
5-判断左括号栈是否为空

class Solution {
public:
    bool isValid(string s) {
        if(s.size()==0) return true;
        if(s.size()==1) return false;//单括号必然无效
        stack<char> lStack;
        for(int i=0;i<s.size();i++){
            if(isLeftBrakets(s[i])){
                lStack.push(s[i]);
            }else if(lStack.empty()){
                return false;//第一个为右括号必然无效
            }else if( !isCouple(lStack.top(),s[i]) ){
                return false;
            }else{
                lStack.pop();
            }
        }
        if(lStack.empty()){
            return true;
        }
        return false;
    }
    
    bool isLeftBrakets(char s){
        if(s=='{' || s=='[' || s=='('){
            return true;
        }
        return false;
    }
    
    bool isCouple(char a,char b){
        if( a=='(' && b==')' ) return true;
        if( a=='[' && b==']')  return true;
        if(a=='{' && b=='}') return true;
        return false;
    }
    
};

2.3 每日温度

一脸懵逼,没想到咋用栈来解决
以温度列表的下标为元素入栈,遍历温度列表,如果当前温度高于栈顶下标对应温度,则该栈顶下标对应结果找到,栈顶弹出;…

    vector<int> dailyTemperatures(vector<int>& T) {
        vector<int> result(T.size(),0);
        
        stack<int> tStack;
        for(int i =0; i<T.size();i++){
            while(!tStack.empty() && T[i]> T[tStack.top()] ){
                result[tStack.top()] = i-tStack.top();
                tStack.pop();
            }
            tStack.push(i);
        }
        
        return result;    
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值