2022-01-06每日刷题打卡
力扣——每日一题
71. 简化路径
给你一个字符串 path ,表示指向某一文件或目录的 Unix 风格 绝对路径 (以 ‘/’ 开头),请你将其转化为更加简洁的规范路径。
在 Unix 风格的文件系统中,一个点(.)表示当前目录本身;此外,两个点 (…) 表示将目录切换到上一级(指向父目录);两者都可以是复杂相对路径的组成部分。任意多个连续的斜杠(即,’//’)都被视为单个斜杠 ‘/’ 。 对于此问题,任何其他格式的点(例如,’…’)均被视为文件/目录名称。
请注意,返回的 规范路径 必须遵循下述格式:
始终以斜杠 ‘/’ 开头。
两个目录名之间必须只有一个斜杠 ‘/’ 。
最后一个目录名(如果存在)不能 以 ‘/’ 结尾。
此外,路径仅包含从根目录到目标文件或目录的路径上的目录(即,不含 ‘.’ 或 ‘…’)。
返回简化后得到的 规范路径 。
示例 1:
输入:path = “/home/”
输出:"/home"
解释:注意,最后一个目录名后面没有斜杠。
为了简单,这里采用的是双端队列,准备一个存储字符串的双端队列sta,和两个字符串str和op,遍历path,如果遍历到字母,就用while循环遍历path,把遍历到的字符都加到str上,当遍历到的字符为‘/’时,结束循环。当用for遍历path时遍历到‘.‘字符,也用while遍历path,把遍历到的字符都加到op上,当遍历到字符为’/‘时结束循环,然后判断op,如果op==“…“且sta不为空,就去掉sta的末尾元素(返回上一级),如果op的长度大于2,就把op也尾插到sta里(这样的情况下,op是个文件夹的名字),如果op长度为一,不做处理(题目的’.'其实一点用没用,忽略即可。当for遍历到的字符为‘/’时,先清空op,再判断str是否为空,如果不为空就把str尾插到sta里,并且清空str。当for遍历结束后,判断sta是否为空,如果为空直接返回一个”/“即可,如果不为空就拿一个字符串遍历sta,每次遍历先给字符串加上一个‘/’做文件夹的分割线,再把sta的头部元素加到字符串后面,且要把头部元素出队,循环下去,当sta为空时结束循环,并把字符串返回。
class Solution {
public:
string simplifyPath(string path) {
deque<string>sta;
path+='/';
string str,op;
int n=path.size();
for(int i=0;i<n;i++)
{
if((path[i]>='a'&&path[i]<='z')||(path[i]>='A'&&path[i]<='Z'))
{
while(path[i]!='/'&&i<n)
{
str+=path[i];
i++;
}
i--;
}
else if(path[i]=='/')
{
if(str.size())
{
sta.push_back(str);
str.clear();
}
op.clear();
}
else if(path[i]=='.')
{
while(path[i]!='/'&&i<n)
{
op+=path[i];
i++;
}
i--;
if(op.size()==2&&!sta.empty())sta.pop_back();
else if(op.size()>=3)sta.push_back(op);
op.clear();
}
}
if(sta.empty())return "/";
while(!sta.empty())
{
str+='/';
str+=sta.front();
sta.pop_front();
}
return str;
}
};
飞书——每日一题
155. 最小栈
设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
push(x) —— 将元素 x 推入栈中。
pop() —— 删除栈顶的元素。
top() —— 获取栈顶元素。
getMin() —— 检索栈中的最小元素。
示例:
输入:
[“MinStack”,“push”,“push”,“push”,“getMin”,“pop”,“top”,“getMin”]
[[],[-2],[0],[-3],[],[],[],[]]
输出:
[null,null,null,null,-3,null,0,-2]
解释:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); --> 返回 -3.
minStack.pop();
minStack.top(); --> 返回 0.
minStack.getMin(); --> 返回 -2.
虽然题目只说需要一个栈,但这里我设计了两个栈,一个栈是正常操作的栈sta,一个是专门存放最小值的栈min_sta,各自准备一个栈顶指针,top_1是sta的,top_2是min_sta的,还有一个记录当前最小值的变量min_num,当要返回最小值元素时,只需要返回它即可。top_1和top_2都指向的是当前栈顶元素的下标,所以如果是空栈,那么它们俩个的值就为-1,当要返回栈顶元素时,直接返回sta[top_1]即可,每次进行push操作,判断要插入的val值和min_num比哪个大,如果是min_num大于等于val,就把min_num插入min_sta重,并且把val值赋给min_num,再把val插入sta中。注意,每插入一个数,栈顶指针++,反之pop出栈顶元素时,我们只需要把栈顶指针–即可。但这里有一点,当弹出的栈顶元素为当前最小值元素时,要把min_num的值改成min_sta栈的栈顶元素,同时栈顶元素出栈。
class MinStack {
public:
int sta[100010],min_sta[100010];
int top_1=-1,min_num=INT_MAX,top_2=-1;
MinStack() {
}
void push(int val) {
sta[++top_1]=val;
if(min_num>=val)
{
min_sta[++top_2]=min_num;
min_num=val;
}
}
void pop() {
if(sta[top_1]==min_num)
{
min_num=min_sta[top_2];
top_2--;
}
top_1--;
}
int top() {
return sta[top_1];
}
int getMin() {
return min_num;
}
};
/**
* Your MinStack object will be instantiated and called as such:
* MinStack* obj = new MinStack();
* obj->push(val);
* obj->pop();
* int param_3 = obj->top();
* int param_4 = obj->getMin();
*/
74. 搜索二维矩阵
编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性:
每行中的整数从左到右按升序排列。
每行的第一个整数大于前一行的最后一个整数。
示例 1:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KXjpxBdu-1641566706090)(https://assets.leetcode.com/uploads/2020/10/05/mat.jpg)]
输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3
输出:true
这题你可以每一层都用一次二分查找来判断改行有没有target,如果有就返回true,如果遍历完所有行也没有就返回false。
但这样实在太麻烦了,有一个更方便的点子,此时你把目光看到这个矩阵右上角,然后你会发现一个事,从右上角开始,他下面的数都大于他,他左边的数都小于他。此时你懂我什么意思了吗,我们从右上角出发,每次把位置上的元素和target做对比,如果相等就返回true;如果大于target,说明target可能在当前元素的下方,然后我们把遍历的位置向下移动一行;对应的,如果小于target,我们就把位置向左移动一行。这样,如果这个矩阵里有target那我们就一定能找到,如果找不到(遍历到的位置超出矩阵的界限),说明矩阵里没有target,返回false。
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
int n=matrix.size(),m=matrix[0].size(),i=0,j=m-1;
while(i<n&&j>=0)
{
if(matrix[i][j]==target)return true;
else if(matrix[i][j]>target)j--;
else if(matrix[i][j]<target)i++;
}
return false;
}
};