leetcode刷题记录-day9

本文记录了作者在LeetCode第9天的刷题心得,涉及179到221题。文章重点讨论了部分题目,如187题的哈希编码优化,199题的层序遍历,207题的BFS解法,213题的环形链表处理,以及215题的小顶堆应用。作者强调了一些题目的解题思路和重要性,特别提到这些题目在微软和字节跳动面试中的高频出现。
摘要由CSDN通过智能技术生成

leetcode刷题记录-day9

179

在这里插入图片描述
1.非常棒的一道题,我要吹爆!微软和字节跳动考察的频率很高的!
2.这题其实就是重新排列一下vector,排序方法是:对于输入的两个字符串,分别用A+B和B+A进行比较即可,相等请返回false(不要返回true谢谢)

bool compare(const int& data1, const int& data2);

class Solution {
public:
    string largestNumber(vector<int>& nums) {
        string ans;
        sort(nums.begin(), nums.end(), compare);
        for(int i = 0; i < nums.size(); ++ i) {
            ans += to_string(nums[i]);
        }
        while(1) {
            if(ans.size() <= 1)
                break;
            else {
                if(ans[0] == '0')
                    ans = ans.substr(1);
                else
                    break;
            }
        }
        return ans;
    }
};

bool compare(const int& data1, const int& data2) {
    string a = to_string(data1) + to_string(data2);
    string b = to_string(data2) + to_string(data1);
    for(int i = 0; i < a.size(); ++ i) {
        if(a[i] == b[i])
            continue;
        else
            return a[i] > b[i];
    }
    return false;
}

186

在这里插入图片描述
1.这道题前面出现过更复杂的,这里我就不搞了,pass!(微软考察了很多次,要注意)

187

在这里插入图片描述
1.这道题虽然考察的很少,但我个人觉得这是个好题目。
2.暴力解法应该是很好想到的,但是这个时间复杂度确实是有点大,且搞个哈希map占用的空间也是不老少。咋办?很简单啊!
3.对这长度为L的字符串进行一个编码!完了每次咱们移动窗口的时候,也就不用再从头算一遍(对字符串进行编码),直接把上一次的编码结果拿过来,然后掐头添尾,时间复杂度直接O(1)!!!ohhhhhhhhhhh这是一种非常棒的思想,一定要记住!!!
4.建议复习时重点思考一遍,pass!

199

在这里插入图片描述
1.字节跳动考察次数爆炸!!!一定要看!一定要看!
2.淦,这题实在是太简单了,我无力吐槽,直接层序遍历就完事儿了,难受啊

200

在这里插入图片描述
1.很难想象,微软和字节跳动居然考察了很多次这道题!!!太简单了吧???醉了醉了,pass!

201

在这里插入图片描述
1.这道题微软和字节倒是没有过多的考察,不过个人认为这是一道非常好的题目。
2.重点在于思路,其实就是求最高位刚开始变化的地方,这个地方以及以后就都是0了。
3.复习时重点思考一遍!

207

在这里插入图片描述
1.这是微软考察次数非常多的一道题!!!
2.bfs了解一下:
在这里插入图片描述
3.这是非常棒的一道题,我觉得有必要上代码仔细看看!考察的概率非常大。

class Solution {
public:
    bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
         vector<int> dimens(numCourses, 0);
         vector<vector<int>> outTable(numCourses, vector<int>());
         for(int i = 0; i < prerequisites.size(); ++ i) {
             dimens[prerequisites[i][1]] ++;
             outTable[prerequisites[i][0]].push_back(prerequisites[i][1]);
         }

        queue<int> details;
         while(1) {
             bool hasOne = false;
             for(int i = 0; i < numCourses; ++ i) {
                 if(dimens[i] == 0) {
                    details.push(i);
                    hasOne = true;
                 }
             }
             if(hasOne == false)
                break;
            while(details.empty() == false) {
                int target = details.front();
                details.pop();
                dimens[target] --;
                for(int i = 0; i < outTable[target].size(); ++ i) {
                    dimens[outTable[target][i]]--;
                }
            }
         }

         for(int i = 0; i < numCourses; ++ i) {
             if(dimens[i] != -1)
                return false;
         }
         return true;
    }
}; 

208

在这里插入图片描述
1.微软考察过两次,字节考察过四次,都不多。根节点不存放任何东西,其余节点都要存放东西。
2.其实结构很简单,首先是个struct描述点:

struct TreeNode{
	char val;
	bool isEoW;
	map<char, TreeNode*> list;
};

这里我用一个map来加速查找过程。
3.对于插入操作,很简单,从root节点开始,如果这个字符在list中没有出现,就构造,一路构造下去。如果出现了,那就沿着人家的路走下去,如果还没走完就结束了,那就将这个地方的标质量置为true。
4.对于查找操作,就很简单了,直接盲目搜索即可,停下来的时候看看这个地方的isEoW是否为true。
5.记得在插入节点的时候,哪怕是叶子节点,也要设置isEoW=true(因为后续可能会继续插入一些单词覆盖这个叶子节点)
6.构造函数记得构造一个根节点(析构函数记得释放这个根节点)

209

在这里插入图片描述
1.这道题是字节跳动考察次数爆炸的一道题!
2.思路其实很简单,就直接左右指针搞一下就好。我还是觉得有必要放代码看看:

class Solution {
public:
    int minSubArrayLen(int s, vector<int>& nums) {
        int ans = 0;
        if(nums.size() != 0) {
            int leftIndex = 0, rightIndex = 1;
            int totSum = nums[0];
            while(rightIndex != nums.size()) {
                if(totSum < s) {
                    totSum += nums[rightIndex++];
                } 
                if(totSum >= s) {
                    //ans = (ans == 0) ? (rightIndex - leftIndex) : ( min(ans, rightIndex - leftIndex) );
                    while(totSum >= s) {
                        ans = (ans == 0) ? (rightIndex - leftIndex) : ( min(ans, rightIndex - leftIndex) );
                        totSum -= nums[leftIndex++];
                    }
                }
            }
        }
        return ans;
    }
};

3.建议复习时重点查看,pass!

210

在这里插入图片描述
1.这道题字节跳动和微软都考察过不少次,不过很可惜的是,这道题和前面的那个课程表很相似,做法就完全一样,只是把结果输出出来而已,没意思,pass

213

在这里插入图片描述
1.这道题字节跳动考察了几次,微软考察的不多。
2.这个思路是真的棒啊!既然是环形,那么就将其断开环路,分成两大类情况,一个是选头不选尾巴,另一个是选尾巴不选头(我这里其实表达的不是很好,我这里的不选,那就一定是不选,甚至是不将其考虑进来;我这里的选,并不是一定选,只是加入考虑)
3.强烈建议把这道题重点复习!上代码:

class Solution {
public:
    int rob(vector<int>& nums) {
        if(nums.size() == 0)
            return 0;
        else if(nums.size() == 1)
            return nums[0];
        else {
            //1.前面n-1的最大值
            vector<int> details(nums.size(), 0);
            details[1] = nums[0];
            for(int i = 1; i < nums.size()-1; ++ i) {
                details[i+1] = max(details[i], details[i-1]+nums[i]);
            }
            int leftMax = details.back();
            //2.后面n-1的最大值
            details[1] = nums[1];
            for(int i = 1; i < nums.size()-1; ++ i) {
                details[i+1] = max(details[i], details[i-1]+nums[i+1]);
            }
            int rightMax = details.back();
            return max(leftMax, rightMax);
        }
    }
};

215

在这里插入图片描述
1.这道题真的非常爆炸,字节跳动和微软都大量使用这个测试题,一定一定要重点关注!!!
2.当然实现方法是非常简单的,就维护一个大小为K的小堆顶,然后写法是要注意的,看代码:

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        priority_queue<int, vector<int>, greater<int>> details;
        for(int i = 0; i < nums.size(); ++ i) {
            details.push(nums[i]);
            if(details.size() > k)
                details.pop();
        }
        return details.top();
    }
};

216

在这里插入图片描述
1.字节跳动和微软考察的很少的一道题,个人觉得这道题不够美妙,就很明显的dfs就完成了,pass!

221

在这里插入图片描述
1.这可是爆款题目!!!各大家都特别喜欢考察!!!
2.我要吹爆这道题,居然是dp!算法实现我直接放在下面:
3.建议复习时一定一定要反复观看!

class Solution {
public:
    int maximalSquare(vector<vector<char>>& matrix) {
        if (matrix.size() == 0 || matrix[0].size() == 0) {
            return 0;
        }
        int maxSide = 0;
        int rows = matrix.size(), columns = matrix[0].size();
        vector<vector<int>> dp(rows, vector<int>(columns));
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < columns; j++) {
                if (matrix[i][j] == '1') {
                    if (i == 0 || j == 0) {
                        dp[i][j] = 1;
                    } else {
                        dp[i][j] = min(min(dp[i - 1][j], dp[i][j - 1]), dp[i - 1][j - 1]) + 1;
                    }
                    maxSide = max(maxSide, dp[i][j]);
                }
            }
        }
        int maxSquare = maxSide * maxSide;
        return maxSquare;
    }
};

4.兄弟,完全可以状态压缩,将空间复杂度降低一个维度,而且你看那个点睛之笔!!!(一定要看啊啊!)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值