向YZT学习。
立志每天刷一道题,提高自己编程实现想法、解决问题的能力,将idea变成code。
注:鉴于本人水平非常有限,以下贴文仅做笔记参考。如有谬误,敬请斧正。
1.队列
1.1知识点
- 队列是先入先出,栈后入先出。
- 循环队列的写法;leetcode上收藏了一个十分经典的循环队列写法。注意该设计末尾指针tail指向空位,并不指向最后一个元素,与STL模板库风格相同。
- 广度优先搜索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.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;
}