c++刷题(3/100)数独,栈和队列

stack的基本操作

s.size():返回栈中的元素数量 
s.empty():判断栈是否为空,返回true或false 
s.push(元素):返回对栈顶部“元素”的可变(可修改)引用 
s.pop():删除栈顶元素,类型为void,但并不返回被删除的元素

s.top():返回栈顶,不删除
s1==s2:若成立,表明s1中的每个元素都等于s2的对应元素,返回true或是false

题目1:用两个栈实现队列

https://www.nowcoder.com/practice/54275ddae22f475981afa2244dd448c6?tpId=13&tqId=11158&tPage=2&rp=2&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking

题目描述

用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。

思路:比较简单,两个栈s1,s2 push的时候就往s1里push,pop的时候,先把s1中的元素全部push到s2,再pop就是队列顺序。这个题也可以描述为如何让栈逆序输出

class Solution
{
public:
    void push(int node) {
        stack1.push(node) ;
    }

    int pop() {
        while(!stack1.empty()){
            stack2.push(stack1.top()) ;
            stack1.pop();
        }
        int res = stack2.top() ;
        stack2.pop() ;
        while(!stack2.empty()){
            stack1.push(stack2.top()) ;
            stack2.pop();
        }
        return res ;
    }

private:
    stack<int> stack1;
    stack<int> stack2;
};

题目2:滑动窗口最大值

https://www.nowcoder.com/practice/1624bc35a45c42c0bc17d17fa0cba788?tpId=13&tqId=11217&tPage=2&rp=2&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking

题目描述

给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}; 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。

思路:这个题O(n*k)很简单,但是要O(n)就有说法了,o(n)的方法是双向队列

先看我的比较挫的版本,用了两个队列:

class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        queue<int> q ;
        deque<int> qmin ;
        vector<int> ans ;
        if(nums.size()==0||k==0){
            return ans ;
        }
        for(int i=0;i<k;i++){
            if(qmin.empty()){
                qmin.push_back(nums[i]) ;
            }else{
                while(!qmin.empty()&&qmin.back()<nums[i]) qmin.pop_back();
                qmin.push_back(nums[i]) ;
            }
            q.push(nums[i]) ;
        }
        ans.push_back(qmin.front()) ;
        for(int i=k;i<nums.size();i++){
            if(qmin.front()==q.front()){
                qmin.pop_front() ;
            }
            q.pop() ;
            q.push(nums[i]) ;
            while(!qmin.empty()&&qmin.back()<nums[i]) qmin.pop_back();
            qmin.push_back(nums[i]) ;
            ans.push_back(qmin.front()) ;
        }
        return ans ;
    }
};

再看网上大神的版本:一个双端队列,代码也比我简洁。。。

class Solution {
public:
    vector<int> maxInWindows(const vector<int>& num, unsigned int size)
    {
        deque<int> qmin ;
        vector<int> ans ;
        int k = size ;
        if(num.size()==0||size==0){
            return ans ;
        }
        for(int i=0;i<num.size();i++){
        // 每当新数进来时,如果发现队列头部的数的下标,是窗口最左边数的下标,则扔掉
            if(!qmin.empty() && qmin.front() == i - k) qmin.pop_front();
            // 把队列尾部所有比新数小的都扔掉,保证队列是降序的
            while(!qmin.empty() && num[qmin.back()] < num[i]) qmin.pop_back() ;
            // 加入新数
            qmin.push_back(i) ;
            // 队列头部就是该窗口内第一大的
            if((i + 1) >= (int)k) ans.push_back(num[qmin.front()]);
        }
        return ans ;
    }
};

题目3:数独

编写一个程序,通过已填充的空格来解决数独问题。

一个数独的解法需遵循如下规则:

  1. 数字 1-9 在每一行只能出现一次。
  2. 数字 1-9 在每一列只能出现一次。
  3. 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。

空白格用 ‘.‘ 表示。

一个数独。

答案被标成红色。

Note:

  • 给定的数独序列只包含数字 1-9 和字符 ‘.‘ 。
  • 你可以假设给定的数独只有唯一解。
  • 给定数独永远是 9x9 形式的。

思路:搜索的题目,在能填数的位置先填一个数,然后判断合法性,如果合法就从该状态下再填下一个数。

本来以为要用A*,结果发现直接搜也没有超时,还有原题目是void函数,没有返回真的难受,搜索的题如果递归函数没有返回那怎么知道找到了没啊。

最后发现别人强行把示例的函数改成了bool型,然后可以过。

最后复习一下个位数的int-》char就是num+‘0‘,char->int就是str-‘0’

class Solution {
public:

    bool checkIsLeagel(vector<vector<char>>& board,int x,int y){
        for(int i=0;i<9;i++){
            if(i!=x&&board[x][y]==board[i][y]){
                return false ;
            }
            if(i!=y&&board[x][y]==board[x][i]){
                return false ;
            }
        }
        for(int i=3*(x/3);i<3*(x/3+1);i++){
            for(int j=3*(y/3);j<3*(y/3+1);j++){
                if(x!=i&&y!=j&&board[x][y]==board[i][j]){
                    return false ;
                }
            }
        }
        return true ;
    }

    bool solveSudoku(vector<vector<char>>& board){
        for(int i=0;i<9;i++){
            for(int j=0;j<9;j++){
                if(board[i][j]==‘.‘){
                    for(int k=1;k<=9;k++){
                        board[i][j] = k + ‘0‘ ;
                        if(checkIsLeagel(board,i,j)&&solveSudoku(board)){
                            return true ;
                        }
                        board[i][j] = ‘.‘ ;
                    }
                    return false ;
                }
            }
        }
        return true ;
    }

};

ps:记录两个数据结构

小顶堆和大顶堆(优先队列):

priority_queue<int, vector<int>, less<int>> maxHeap; //存储小的值,值越大,优先级越高
priority_queue<int, vector<int>, greater<int>> minHeap; //存储大的值,值越小,优先级越高
  双向队列:
  1. deq[ ]:用来访问双向队列中单个的元素。
  2. deq.front():返回第一个元素的引用。
  3. deq.back():返回最后一个元素的引用。
  4. deq.push_front(x):把元素x插入到双向队列的头部。
  5. deq.pop_front():弹出双向队列的第一个元素。
  6. deq.push_back(x):把元素x插入到双向队列的尾部。
  7. deq.pop_back():弹出双向队列的最后一个元素。

  deque的一些特点

  1. 支持随机访问,即支持[ ]以及at(),但是性能没有vector好。
  2. 可以在内部进行插入和删除操作,但性能不及list。
  3. deque两端都能够快速插入和删除元素,而vector只能在尾端进行。
  4. deque的元素存取和迭代器操作会稍微慢一些,因为deque的内部结构会多一个间接过程。
  5. deque迭代器是特殊的智能指针,而不是一般指针,它需要在不同的区块之间跳转。
  6. deque可以包含更多的元素,其max_size可能更大,因为不止使用一块内存。
  7. deque不支持对容量和内存分配时机的控制。
  8. 在除了首尾两端的其他地方插入和删除元素,都将会导致指向deque元素的任何pointers、references、iterators失效。不过,deque的内存重分配优于vector,因为其内部结构显示不需要复制所有元素。
  9. deque的内存区块不再被使用时,会被释放,deque的内存大小是可缩减的。不过,是不是这么做以及怎么做由实际操作版本定义。
  10. deque不提供容量操作:capacity()和reverse(),但是vector可以。

原文地址:https://www.cnblogs.com/maskmtj/p/9256586.html

时间: 2024-10-13 11:41:35

c++刷题(3/100)数独,栈和队列的相关文章

【刷题】【单调栈】音乐会的等待

N个人正在排队进入一个音乐会.人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人.队列中任意两个人A和B,如果他们是相邻或他们之间没有人比A或B高,那么他们是可以互相看得见的. 写一个程序计算出有多少对人可以互相看见. 重点: (1)看题要仔细 (2)不开long long 见祖宗 解法神奇 #include<cstdio> #include<cstdlib> #include<stack> #define ll long long using namesp

刷题总结——生日礼物(bzoj1293单调队列)

题目: Description 小西有一条很长的彩带,彩带上挂着各式各样的彩珠.已知彩珠有N个,分为K种.简单的说,可以将彩带考虑为x轴,每一个彩珠有一个对应的坐标(即位置).某些坐标上可以没有彩珠,但多个彩珠也可以出现在同一个位置上. 小布生日快到了,于是小西打算剪一段彩带送给小布.为了让礼物彩带足够漂亮,小西希望这一段彩带中能包含所有种类的彩珠.同时,为了方便,小西希望这段彩带尽可能短,你能帮助小西计算这个最短的长度么?彩带的长度即为彩带开始位置到结束位置的位置差. Input 第一行包含两

SDUT 2449 数据结构实验之栈与队列十:走迷宫

数据结构实验之栈与队列十:走迷宫 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 一个由n * m 个格子组成的迷宫,起点是(1, 1), 终点是(n, m),每次可以向上下左右四个方向任意走一步,并且有些格子是不能走动,求从起点到终点经过每个格子至多一次的走法数. Input 第一行一个整数T 表示有T 组测试数据.(T <= 110) 对于每组测试数据: 第一行两个整数n, m,表示迷宫有n * m 个格子.(1

leecode刷题(9)-- 有效的数独

leecode刷题(9)-- 有效的数独 有效的数独 描述: 判断一个 9x9 的数独是否有效.只需要根据以下规则,验证已经填入的数字是否有效即可. 数字 1-9 在每一行只能出现一次. 数字 1-9 在每一列只能出现一次. 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次. 上图是一个部分填充的有效的数独. 数独部分空格内已填入了数字,空白格用 '.' 表示. 示例 1: 输入: [ ["5","3",".",".&qu

leecode刷题(26)-- 用栈实现队列

leecode刷题(26)-- 用栈实现队列 用栈实现队列 使用栈实现队列的下列操作: push(x) -- 将一个元素放入队列的尾部. pop() -- 从队列首部移除元素. peek() -- 返回队列首部的元素. empty() -- 返回队列是否为空. 示例: MyQueue queue = new MyQueue(); queue.push(1); queue.push(2); queue.peek(); // 返回 1 queue.pop(); // 返回 1 queue.empty

LeetCode刷题 笨方法 100%通过

今天闲来无事去力扣刷题 有一道题 百思不得其解 又不想去看题解 (习惯答完之后去看) 就想到一个特别‘机智’的方法(*/ω\*) 题目: 如果我们交换字符串 X 中的两个不同位置的字母,使得它和字符串 Y 相等,那么称 X 和 Y 两个字符串相似. 例如,"tars" 和 "rats" 是相似的 (交换 0 与 2 的位置): "rats" 和 "arts" 也是相似的,但是 "star" 不与 "

BZOJ 刷题记录 PART 3

[前言]还是强调要少看题解. [BZOJ1090]简单的区间DP.值得注意的是:在压缩的时候,如果是10个A压缩,那么化成(10)A后有5个字符而不是4个!(我在这里被坑了好长时间!)以下是核心代码: for (len=2;len<=L;len++) for (i=1;i<=L-len+1;i++) { j=i+len-1; for (k=i;k<j;k++) f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]); for (l=1;l<=len/2;l++

编程日志&amp;&amp;刷题日志&amp;&amp;开发日志迁移之碎碎念

Given an array of integers, return indices of the two numbers such that they add up to a specific target. You may assume that each input would have exactly one solution, and you may not use the same element twice. Example: Given nums = [2, 7, 11, 15]

用js刷题的一些坑

leecode可以用js刷题了,我大js越来越被认可了是吧.但是刷题中会因为忽略js的一些特性掉入坑里.我这里总结一下我掉过的坑. 坑1:js中数组对象是引用对象 js中除了object还有数组对象也是引用对象,这点常常被忽视,所以在递归的时候传递数组要用arr.slice(0)这样复制一个一样的新数组,不然会出现你传入的数组会被同级的递归改变,结果就不对了. 所以只要数组复制的地方最好都要这么写,除非你真的想引用.而且注意是slice不是splice这两个方法差别很大,你如果用splice(0