2022-01-06每日刷题打卡

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;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值