LeetCode八月每日一题题解(个人记录打卡)

文章目录

  • 八月每日一题
    • 1374. 生成每种字符都是奇数个的字符串
    • 622. 设计循环队列
    • 899. 有序队列
    • 1403. 非递增顺序的最小子序列
    • 623.在二叉树中增加一行
    • 1408. 数组中的字符串匹配
    • 636. 函数的独占时间(不会)
    • 761. 特殊的二进制序列(不会)
    • 1413. 逐步求和得到正数的最小值
    • 640. 求解方程(不会)
    • 1417重新格式化字符串
    • 1282. 用户分组
    • 768. 最多能完成排序的块 II
    • 1422. 分割字符串的最大得分
    • 641. 设计循环双端队列
    • 1656. 设计有序流
    • 1302. 层数最深叶子节点的和
    • 1224. 最大相等频率(不会)
    • 1450. 在既定时间做作业的学生人数
    • 654. 最大二叉树
    • 998. 最大二叉树 II
    • 1455. 检查单词是否为句中其他单词的前缀
    • 655. 输出二叉树
    • 782. 变为棋盘(不会)
    • 1460. 通过翻转子数组使两个数组相等
    • 658. 找到 K 个最接近的元素
    • 1464. 数组中两元素的最大乘积
    • 662. 二叉树最大宽度
    • 793. 阶乘函数后 K 个零(不会)
    • 1470. 重新排列数组
    • 946. 验证栈序列
    • 总结

八月每日一题

1374. 生成每种字符都是奇数个的字符串

https://leetcode.cn/problems/generate-a-string-with-characters-that-have-odd-counts/

LeetCode八月每日一题题解(个人记录打卡)_第1张图片

思路:如果为奇数 返回一个b+奇数个a,若为偶数返回全部的a

class Solution {
public:
    string generateTheString(int n) {
   if(n%2!=0){
       return string(n,'a'); 
   }else{
       return 'b'+string(n-1,'a');
   }
    }
};

622. 设计循环队列

https://leetcode.cn/problems/design-circular-queue/

LeetCode八月每日一题题解(个人记录打卡)_第2张图片

思路: 数组模拟

  1. 在判断为空和为满的时候需要用一个空的位置进行标记
  2. 入队之前要检查是否为满
  3. 出队之前要检查是否为空
  4. 满的判断条件 front == (rear+1)%size
  5. 空的判断条件 rear == front
  6. 找队尾的条件 (rear - 1 + capacity) % capacity 而非 rear
class MyCircularQueue {
private:
int size;
vector queue;
int rear;
int front;
public:
    MyCircularQueue(int k) {
        this->size = k+1;
        this->front=this->rear=0;
        queue = vector(this->size);

    }
    
    bool enQueue(int value) {
     //插入之前判断是否满
     if(isFull())return false;
     queue[rear] = value;
     rear = (rear+1)%size;
     return true;

    }
    
    bool deQueue() {
        if(isEmpty())return false;
        front = (front+1) %size;
        return true;
    }
    
    int Front() {
   if(isEmpty())return -1;
   return queue[this->front];
    }
    
    int Rear() {
        if(isEmpty())return -1;
        // return queue[this->rear];
         return queue[(rear - 1 + size) % size];
    }
    
    bool isEmpty() {
        return this->rear == this->front;
    }
    
    bool isFull() {
        return this->front == (this->rear+1)%this->size;
    }
};

899. 有序队列

https://leetcode.cn/problems/orderly-queue/

LeetCode八月每日一题题解(个人记录打卡)_第3张图片

思路:

  1. 如果k等于1,那么就找到所有移动过程中形成的字符串字典树最小的
  2. 如果k!=1,直接排序,得到字典树最小的
class Solution {
public:
    string orderlyQueue(string s, int k) {
       //

       if(k==1){
           string smallStr=s;
         
           for(int i=0;i

1403. 非递增顺序的最小子序列

https://leetcode.cn/problems/minimum-subsequence-in-non-increasing-order/

LeetCode八月每日一题题解(个人记录打卡)_第4张图片

思路:

根据题目要求,我们要尽可能是的找到的子序列的长度最小, 同时如果长度相等,我们要找到一个长度相等情况下,元素之和最小的。

因此,根据这个条件我们可以对数组进行递减排序。

从前往后将遍历到的元素加入到res当中,比较当前res元素之和是否大于nums数组剩余的元素之和,如果大于就返回res,即找到一个符合题目条件的序列

class Solution {
public:
    vector minSubsequence(vector& nums) {
    //找到子序列,要大于剩余的
    //优先排序
    int n=nums.size();
     sort(nums.rbegin(),nums.rend());
    vector res;
    for(int i=0;icurNumRight){
            return res;
        }
    }
     return res;
    }
   
};

623.在二叉树中增加一行

LeetCode八月每日一题题解(个人记录打卡)_第5张图片

思路:dfs递归

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* addOneRow(TreeNode* root, int val, int depth) {
       if(root ==nullptr){return nullptr;}
       if(depth ==1){
           return new TreeNode(val,root,nullptr);
       }
       if(depth ==2){
           root->left =new TreeNode(val,root->left,nullptr);
           root->right = new TreeNode(val,nullptr,root->right);
       }else{
           root->left = addOneRow(root->left,val,depth-1);
           root->right = addOneRow(root->right,val,depth-1);
       }
       return root;

    }
};

思路:bfs广度遍历

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* addOneRow(TreeNode* root, int val, int depth) {
        //根据题目要求的第一个条件
        if(depth==1) return new TreeNode(val,root,nullptr);
        //用队列来模拟广度
        queue q;
        //先将根节点入队
        q.push(root);
        //h用于记录当前的高度
        for(int h=1;!q.empty();h++){
            //找到相应高度进行插入元素
            if(h==depth-1){
                while(!q.empty()){
                    //找到当前的根节点
                    TreeNode* cur=q.front();
                    //根节点出队
                    q.pop();
                    //为当前的根节点左右子树插入相应元素,并将原左右子树分配给现在插入的左右的两个元素的左边以及右边
                    cur->left =new TreeNode(val,cur->left,nullptr);
                    cur->right = new TreeNode(val,nullptr,cur->right);
                }
            }
            //如果没有找到当前的插入位置,就需要不断入队
            for(int i=q.size();i>0;i--){
                TreeNode* cur=q.front();
                q.pop();
                if(cur->left!=nullptr){ q.push(cur->left);}
                if(cur->right!=nullptr){q.push(cur->right);}
            }
        }
        return root;

    }
};

1408. 数组中的字符串匹配

https://leetcode.cn/problems/string-matching-in-an-array/

LeetCode八月每日一题题解(个人记录打卡)_第6张图片

class Solution {
public:
    vector stringMatching(vector& words) {
        string s;
         vector res;
        for(auto word:words){
            s+=" "+word;
        }
          for(auto word:words){
              if(s.find(word)!=s.rfind(word)){
                  res.push_back(word);
              }
          }
          return res;
    }
};

find() 正向查找要匹配字符串的第一个字符出现的位置

rfind()反向查找要匹配的字符串的第一个字符出现的位置

对于上面两个函数,若查找失败 则会返回一个特殊标记npos,一般写做string::npos

  1. 首先将数组拼接成一个字符串 以空格分隔
  2. 通过正向和反向查找字符串,如果通过正向和反向查找到得位置不是同一个位置,则说明时符合条件得(比如查找 as,正向查找得返回得结果为2,负向查找的结果为6 s为 " mass as … ")

636. 函数的独占时间(不会)

https://leetcode.cn/problems/exclusive-time-of-functions/

LeetCode八月每日一题题解(个人记录打卡)_第7张图片

思路:

class Solution {
public:
    vector exclusiveTime(int n, vector& logs) {
        stack> st; // {idx, 开始运行的时间}
        vector res(n, 0);
        for (auto& log : logs) {
            char type[10];
            int idx, timestamp;
            sscanf(log.c_str(), "%d:%[^:]:%d", &idx, type, ×tamp);
            if (type[0] == 's') {
                if (!st.empty()) {
                    res[st.top().first] += timestamp - st.top().second;
                    st.top().second = timestamp;
                }
                st.emplace(idx, timestamp);
            } else {
                auto t = st.top();
                st.pop();
                res[t.first] += timestamp - t.second + 1;
                if (!st.empty()) {
                    st.top().second = timestamp + 1;
                }
            }
        }
        return res;
    }
};

761. 特殊的二进制序列(不会)

https://leetcode.cn/problems/special-binary-string/)

LeetCode八月每日一题题解(个人记录打卡)_第8张图片

思路就是:把 0,1 看成 ( )括号

class Solution {
public:
    string makeLargestSpecial(string s) {
       if(s.size()<2){return s;}
       int cnt =0,left =0;
       vector subs;
       for(int i=0;i{});
       string ans = accumulate(subs.begin(),subs.end(),""s);
       for(int i=0;i

1413. 逐步求和得到正数的最小值

https://leetcode.cn/problems/minimum-value-to-get-positive-step-by-step-sum/

LeetCode八月每日一题题解(个人记录打卡)_第9张图片

思路:贪心

题目要求所有累加和都要大于等于一,只要满足最小的累加和+startValue>=1即可 那么startValue的最小值即为 1-sumMin

class Solution {
public:
    int minStartValue(vector& nums) {
            int sum=0;int sumMin=0;
            for(int num:nums){
                sum+=num;
                sumMin = min(sum,sumMin);
            }
            //sumMin+startValue >=1;
            return  1-sumMin;
    }
};

640. 求解方程(不会)

https://leetcode.cn/problems/solve-the-equation

LeetCode八月每日一题题解(个人记录打卡)_第10张图片

class Solution {
public:
    string solveEquation(string equation) {
        int factor = 0, val = 0;
        int index = 0, n = equation.size(), sign1 = 1; // 等式左边默认系数为正
        while (index < n) {
            if (equation[index] == '=') {
                sign1 = -1; // 等式右边默认系数为负
                index++;
                continue;
            }

            int sign2 = sign1, number = 0;
            bool valid = false; // 记录 number 是否有效
            if (equation[index] == '-' || equation[index] == '+') { // 去掉前面的符号
                sign2 = (equation[index] == '-') ? -sign1 : sign1;
                index++;
            }
            while (index < n && isdigit(equation[index])) {
                number = number * 10 + (equation[index] - '0');
                index++;
                valid = true;
            }

            if (index < n && equation[index] == 'x') { // 变量
                factor += valid ? sign2 * number : sign2;
                index++;
            } else { // 数值
                val += sign2 * number;
            }
        }

        if (factor == 0) {
            return val == 0 ? "Infinite solutions" : "No solution";
        }
        return string("x=") + to_string(-val / factor);
    }
};

1417重新格式化字符串

https://leetcode.cn/problems/reformat-the-string/

LeetCode八月每日一题题解(个人记录打卡)_第11张图片

思路:

  1. 统计数字和字母分别有多少个字符,再用两个string,分别来存储字母和数字
  2. 如果两个字符串大小相差大于1,则说明根本无法满足题目进行交换
  3. 让字符大小大的先存(否则,比如covid2019,如果按照数字先存,则 2c0o1v9id,不符合要求,而是c2o0v1i9d符合要求),所以需要交换字符串,让一个字符串始终存放长的字符串,另一个存放短的
  4. 定义两个指针分别指向两个新的字符串,遍历追加到最终结果当中
class Solution {
public:
  string reformat(string s) {
    int cnt1 = 0;
    int cnt2 = 0;
    string str1 = "";
    string str2 = "";
    string res = "";
     //统计字母,数字字符串的大小,以及追加到两个数组当中国
    for (int i = 0; i < s.size(); i++) {
        if (isdigit(s[i])) { cnt1++; str1 += s[i]; }
        else if (isalpha(s[i])) { cnt2++; str2 += s[i]; }
    }
      //如果字母和数字的数字个数大于1,则无法满足题意格式化
    if (abs(cnt1 - cnt2) > 1)return "";
    int i = 0, j = 0;
    //始终确保str1是最长的那个,优先填充最长的那个
    if(str1.size()

1282. 用户分组

https://leetcode.cn/problems/group-the-people-given-the-group-size-they-belong-to/

LeetCode八月每日一题题解(个人记录打卡)_第12张图片

思路:

首先需要理解groupSizes表示的是对应对应下标的人应该存在大小为多少的组里面(某个身份的人,应该睡在几人间)

题目最后要求的就是通过上述的划分,那些人应该睡在几人间(一人间睡那一个人,三人间睡哪三个人)

  1. 定义一个hashmap用于存储数组大小为x的存放哪几个人(可能超过了x大小,比如用例1)
  2. 接下来就需要对可能超过数组大小(房间人数)的这些人进行处理,分成几个房间(房间大小x)
  3. 最后将划分的结果存在最终的答案当中
class Solution {
public:
    vector> groupThePeople(vector& groupSizes) {
        vector> res;
        unordered_map>mp;
        int i=0;
        //先按照组大小进行划分 ID为多少的存放在多大的组内
      for(i=0;i g; 
             //每一组的起始位置
             int start = i*size;
            
             for(int j=0;j

768. 最多能完成排序的块 II

https://leetcode.cn/problems/max-chunks-to-make-sorted-ii/

LeetCode八月每日一题题解(个人记录打卡)_第13张图片

思路:单调栈

如果当前元素小于栈顶元素,则用变量maxNum记录栈顶元素,如果栈不为空且栈顶元素大于当前元素,则出栈。同时将当前元素存入栈中,作为一个区间块的标记

class Solution {
public:
    int maxChunksToSorted(vector& arr) {
        stack st;
        st.push(arr[0]);
        int res=0;
        for(int i=1;iarr[i]) st.pop();
              st.push(maxNum);
          }else{
              st.push(arr[i]);
          }
        }
        return st.size();
    }
};

1422. 分割字符串的最大得分

https://leetcode.cn/problems/maximum-score-after-splitting-a-string/

LeetCode八月每日一题题解(个人记录打卡)_第14张图片

思路一:暴力

一个一个试分割点,将字符串分割为左右两边,在统计左边0的个数以及右边1的个数

最后取最大值

class Solution {
public:
    int maxScore(string s) {
        int res=0;
        int n = s.size();
        // //标记位置
        for(int i=1;i

思路二:前缀和和后缀和

sumL统计i之前的0的个数

sumR统计i之后1的个数

每个位置分开的分数即为left[i] + right[i+1];
遍历取最大即可。

class Solution {
public:
    int maxScore(string s) {
 int n = s.length();
 int res=0;
        int sum =0;
        vector sumL(n);
        vector sumR(n);
        //统计前缀和 0 的个数
        for(int i=0;i=0;i--){
            if(s[i]=='1'){
                sum++;
            }
            sumR[i]+=sum;
        }
            for(int i=0;i

641. 设计循环双端队列

https://leetcode.cn/problems/design-circular-deque/

LeetCode八月每日一题题解(个人记录打卡)_第15张图片

思路 和前面 622设计循环队列类似的思路

class MyCircularDeque {
public:
 vector element;
    int rear, front;
    int capacity;
    MyCircularDeque(int k) {
         rear=0;
         front=0;
         capacity = k+1;
        element = vector(k+1);
    }
    
    bool insertFront(int value) {
        if(isFull())return false;
         front = (front-1+capacity)%capacity;
        element[front] = value;
        return true;
    }
    
    bool insertLast(int value) {
        if(isFull())return false;
        element[rear] = value;
        rear = (rear+1)%capacity;
          return true;
    }
    
    bool deleteFront() {
        if(isEmpty())return false;
          front = (front+1)%capacity;
          return true;
    }
    
    bool deleteLast() {
         if(isEmpty())return false;
            rear = (rear - 1 + capacity) % capacity;
          return true;
    }
    
    int getFront() {
         if(isEmpty())return -1;
         return element[front];
    }
    
    int getRear() {
 if(isEmpty())return -1;
   return element[(rear - 1 + capacity) % capacity];
    }
    
    bool isEmpty() {
        return rear ==front;
    }
    
    bool isFull() {
        return (rear+1)%capacity==front;
    }
};

1656. 设计有序流

https://leetcode.cn/problems/design-an-ordered-stream/

LeetCode八月每日一题题解(个人记录打卡)_第16张图片

思路:

不管怎么样,都现在id下面先插入元素,如果说ptr指向的元素为空或者ptr超出了整个数组长度,直接返回结果。 如果ptr指向的不为空且长度为超过整个数组的长度那么将当前ptr指向的加入到结果res当中,同时ptr指针往后移动。

class OrderedStream {
public:
    vector v;
    int ptr=1;
    int id;
    OrderedStream(int n) {
        v=vector(n+1);
    }
    
    vector insert(int idKey, string value) {
         v[idKey] = value;
         vector res;
         while (ptr < v.size() && !v[ptr].empty()) {
            res.push_back(v[ptr]);
            ++ptr;
        }
        return res;
        }

};

1302. 层数最深叶子节点的和

https://leetcode.cn/problems/deepest-leaves-sum/

LeetCode八月每日一题题解(个人记录打卡)_第17张图片

思路:bfs

记录每一层结点之后,到了最后一层即为要求的结点之和。这里要注意sum的放置位置(要在每一层之前进行初始化操作)

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    int deepestLeavesSum(TreeNode* root) {
        int sum;
        queue q;
        if(root==nullptr){return 0;}
        //根结点先入队
        q.push(root);
        while(!q.empty()){\
            //每一层的总和 sum
            sum =0;
            //每一层结点的个数
            int curSize = q.size();
            for(int i=0;ival;
                if(t->left!=nullptr){q.push(t->left);}
                if(t->right!=nullptr){q.push(t->right);}
            }
            //打印每一层结点总和  (最后的和即为最深层的结点和)
              cout<

1224. 最大相等频率(不会)

https://leetcode.cn/problems/maximum-equal-frequency/

LeetCode八月每日一题题解(个人记录打卡)_第18张图片

思路:

class Solution {
public:
    int maxEqualFreq(vector& nums) {
        map mp;
        map> mp2;
        int ans=1;
        for(int i=0;i(nums[i],1));
                if(mp2.find(1)==mp2.end()){
                    vector mid;
                    mid.push_back(nums[i]);
                    mp2.insert(pair>(1,mid));
                }
                else{
                    mp2[1].push_back(nums[i]);
                }
            }
            else{
                remove(mp2[mp[nums[i]]].begin(),mp2[mp[nums[i]]].end(),nums[i]);
                mp2[mp[nums[i]]].pop_back();
                if(mp2[mp[nums[i]]].size()==0){
                    // cout< mid;
                    mid.push_back(nums[i]);
                    mp2.insert(pair>(l+1,mid));
                }
                else{
                    mp2[l+1].push_back(nums[i]);
                }
            }
            // cout<>::iterator it=mp2.begin();it!=mp2.end();it++){
                
            //     cout<first<<"  "<second.size()<>::iterator it=mp2.begin();
                if(it->first!=1&&it->second.size()!=1){
                    continue;
                }
                ans=max(ans,i);
            }
            else if(mp2.size()==2){
                // cout<>::iterator it=mp2.begin();it!=mp2.end();it++){
                    if(it==mp2.begin()){
                        pre=it->first;presize=it->second.size();
                    }
                    else{
                        now=it->first;nowsize=it->second.size();
                    }
                }
                if(pre==1&&presize==1){
                    ans=max(ans,i);
                }
                if(now-pre==1&&nowsize==1){
                    ans=max(ans,i);
                }
            }
            else{
                continue;
            }
        }
        // for(map::iterator it=mp.begin();it!=mp.end();it++){
        //     cout<first<<"  "<second<

1450. 在既定时间做作业的学生人数

https://leetcode.cn/problems/number-of-students-doing-homework-at-a-given-time/

LeetCode八月每日一题题解(个人记录打卡)_第19张图片

思路:

比较querTime是否在start[i]和end[i]当中即可 (start和end数组在长度上一样的)

class Solution {
public:
    int busyStudent(vector& startTime, vector& endTime, int queryTime) {
        int res=0;
        int n = startTime.size();
        for(int i=0;i=queryTime ){
                res++;
            }
        }
        return res;
    }
};

654. 最大二叉树

https://leetcode.cn/problems/maximum-binary-tree/

LeetCode八月每日一题题解(个人记录打卡)_第20张图片

思路:递归

  1. 明确递归结束条件 l>r 表明当前数组已经无元素,返回nullptr
  2. 明确每一次递归的目的是找到当前数组段的最大值,并记录最大值的位置,方便递归左右段数组
  3. 递归左右段数组,构建为root的左右子树上去
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* maxTree(vector& nums,int left,int right){
        if(left>right){return nullptr;}
        //找出当前段中的最大结点
        int mid=left;
        int max=-1;
        for(int i=left;i<=right;i++){
            if(nums[i]>max){max = nums[i];mid = i;
            //cout<left = maxTree(nums,left,mid-1);
        root->right = maxTree(nums,mid+1,right);
        return root;

    }
    TreeNode* constructMaximumBinaryTree(vector& nums) {
        return maxTree(nums,0,nums.size()-1);
       
    }
};

思路二 单调栈

LeetCode八月每日一题题解(个人记录打卡)_第21张图片

  1. 遍历数组nums,如果当前队不空且现在访问的数组小于栈顶的元素且队不为空,将栈顶元素的右指针指向当前数组元素构成的结点
  2. 否则,将当前数组元素构成的结点的左指针指向队顶元素
  3. 最后返回队列的末尾元素
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* constructMaximumBinaryTree(vector& nums) {
        deque q;
        int n =nums.size();
        for(int i=0;iq.front()->val){
             node->left = q.front();
             q.pop_front();
         }
         if(!q.empty()){
            // cout<< q.front()->val<right = node;
         }
         // cout<val<

998. 最大二叉树 II

https://leetcode.cn/problems/maximum-binary-tree-ii/

LeetCode八月每日一题题解(个人记录打卡)_第22张图片

1455. 检查单词是否为句中其他单词的前缀

https://leetcode.cn/problems/check-if-a-word-occurs-as-a-prefix-of-any-word-in-a-sentence/

LeetCode八月每日一题题解(个人记录打卡)_第23张图片

思路:

遍历sentence 根据‘ ’来划分单词,然后通过当前单词是否与searchWord匹配。注意要对第一个单词特殊处理一下

class Solution {
public:
    int isPrefixOfWord(string sentence, string searchWord) {
        int ans = -1;
        int n =sentence.size();
        int  word_index =1;
        for(int i=0;i

655. 输出二叉树

https://leetcode.cn/problems/print-binary-tree/

LeetCode八月每日一题题解(个人记录打卡)_第24张图片

思路:

  1. 首先要知道二叉树的高度,才可以知道m,n 因此先算出高度h
  2. 有了h之后需要递归进行初始化二维数组,根据题目规则的后面几个条件可知,当此刻结点为r,c的位置的时候,左子结点在r+1,c - pow(2,h-r-1),右子结点在r+1,c + pow(2,h-r-1)
  3. 递归的初始r,c 分别为 0 (n-1)/2
class Solution {
public:
//计算树的高度
    int TreeHeight(TreeNode* root){
        if(root==nullptr)return 0;
        return max(TreeHeight(root->left),TreeHeight(root->right))+1;

    }
    //构建二维数组
     void bulidTree(vector> &res,TreeNode* root,int r,int c,const int& h){
         //此刻的结点应该存放的位置
         res[r][c] =to_string(root->val);
         //左子结点的位置
         if(root->left){bulidTree(res,root->left,r+1,c - pow(2,h-r-1),h);}
         右子结点的位置
         if(root->right){
           bulidTree(res,root->right,r+1,c + pow(2,h-r-1),h);
         }
    
     }
    vector> printTree(TreeNode* root) {
      //  m = h+1;  n = 2^(h+1)  -1    根结点位于res[0][(n-1)/2] 
       //根据高度 得出n m
       int h =TreeHeight(root)-1;
       //cout<>  res(m,vector(n,""));
     bulidTree(res,root,0,(n-1)/2,h);
    return res;
    }
};

782. 变为棋盘(不会)

https://leetcode.cn/problems/transform-to-chessboard/

1460. 通过翻转子数组使两个数组相等

https://leetcode.cn/problems/make-two-arrays-equal-by-reversing-sub-arrays/

思路:

如果arr 长度是 11,那么只需判断arr 和 target 是否相同即可。因为此时翻转非空子数组的过程并不会改变数组,只需判断原数组是否相同即可。

如果 arr 长度大于 11,那么首先证明通过一次或二次翻转过程,可以实现数组 arr 中任意两个元素交换位置并且保持其他元素不动。如果想要交换两个相邻元素的位置,那么翻转这两个元素组成的子数组即可。如果想要交换两个非相邻元素的位置,那么首先翻转这两个元素及其中间所有元素组成的子数组,再翻转这两个元素中间的元素组成的子数组即可。这样下来,通过一次或二次翻转过程,即可交换数组中任意两个元素的位置。一旦一个数组中任意两个元素可以交换位置,那么这个数组就能实现任意重排。只需要arr 和 target 元素相同,arr 就能通过若干次操作变成 target。(自己补充:所以可以采用排序的方式进行)

作者:LeetCode-Solution
链接:https://leetcode.cn/problems/make-two-arrays-equal-by-reversing-sub-arrays/solution/tong-guo-fan-zhuan-zi-shu-zu-shi-liang-g-dueo/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

class Solution {
public:
    bool canBeEqual(vector& target, vector& arr) {
       unordered_map counts1, counts2;
        for (int num : target) {
            counts1[num]++;
        }
        for (int num : arr) {
            counts2[num]++;
        }
        if(counts1.size() !=counts2.size())return false;
        for(auto&[key,value]:counts1){
            //如果counts2 中不包含 counts1中的元素   或者 counts2中某个元素的个数不等于count1中某个元素的个数则肯定不能翻转成功
            if(!counts2.count(key) || counts2[key]!=value){return false;}
        }
        return true;
    }
};
class Solution {
public:
    bool canBeEqual(vector& target, vector& arr) {
        sort(arr.begin(),arr.end());
        sort(target.begin(),target.end());
        int n = target.size();
        for(int i=0;i

658. 找到 K 个最接近的元素

https://leetcode.cn/problems/find-k-closest-elements/

思路: 双指针

指针分别指向左边界和右边界 最后需要删除 数组长度-k长度的元素

具体删除是根据 左指针和右指针位于x的距离而进行指针的移动操作进行的

class Solution {
public:
    vector findClosestElements(vector& arr, int k, int x) {
      int l=0,r=arr.size()-1;
      int deleteNum = arr.size()-k;
      while(deleteNum){
          
          if(abs(arr[l]-x)>abs(arr[r]-x)){
              l++;
          }else{
              r--;
          }
          deleteNum--;
      }
      return vector(arr.begin()+l,arr.begin()+l+k);
    }
};

1464. 数组中两元素的最大乘积

https://leetcode.cn/problems/maximum-product-of-two-elements-in-an-array/

思路:

方法一:两重for循环遍历数组

方法二:通过sort函数排序,找到最大元素和次大的元素

方法三:直接通过一层遍历找到最大元素和次大的元素

class Solution {
public:
    int maxProduct(vector& nums) {
        int max =-100;
        int n=nums.size();
        for(int i=0;imax){
                    max = x;
                }
            }
        }
        return max;
    }
};
class Solution {
public:
    int maxProduct(vector& nums) {
          sort(nums.rbegin(), nums.rend());
        return (nums[0] - 1) * (nums[1] - 1);
    }
};
class Solution {
public:
    int maxProduct(vector& nums) {
         int maxFirst=nums[0];
         int maxSecond = nums[1];
         if(maxFirstmaxFirst){
                 maxSecond = maxFirst;
                 maxFirst = nums[i];
                 
             }
             //如果当前元素比次大值大,则更新次大值即可
             else if(nums[i]>maxSecond){
                 maxSecond = nums[i];
               
             }
         }
         return (maxFirst-1)*(maxSecond-1);
    }
};

662. 二叉树最大宽度

https://leetcode.cn/problems/maximum-width-of-binary-tree/

LeetCode八月每日一题题解(个人记录打卡)_第25张图片

思路:

793. 阶乘函数后 K 个零(不会)

https://leetcode.cn/problems/preimage-size-of-factorial-zeroes-function/

LeetCode八月每日一题题解(个人记录打卡)_第26张图片

思路:

class Solution {
public:
    int zeta(long x) {
        int res = 0;
        while (x) {
            res += x / 5;
            x /= 5;
        }
        return res;
    }

    long long help(int k) {
        long long r = 5LL * k;
        long long l = 0;
        while (l <= r) {
            long long mid = (l + r) / 2;
            if (zeta(mid) < k) {
                l = mid + 1;
            } else {
                r = mid - 1;
            }
        }
        return r + 1;
    }

    int preimageSizeFZF(int k) {
        return help(k + 1) - help(k);
    }
};

1470. 重新排列数组

https://leetcode.cn/problems/shuffle-the-array/

LeetCode八月每日一题题解(个人记录打卡)_第27张图片

思路:

根据示例可以看出来数组是按照对半交叉进行重新组合的,只需要定义一个新的数组存储重新组合后的数组,两个指针分别指向0 和中间元素,不断添加两个指针指向的元素即可

class Solution {
public:
    vector shuffle(vector& nums, int n) {
    vector res;
    int i=0,j=n;
    while(i

946. 验证栈序列

https://leetcode.cn/problems/validate-stack-sequences/

LeetCode八月每日一题题解(个人记录打卡)_第28张图片

思路:

  1. 遍历pushed数组 将其中的值依次进栈
  2. 每将pushed的元素入栈之后,如果栈不为空且栈顶元素和poped数组的当前元素相等,则栈顶元素出栈
class Solution {
public:
    bool validateStackSequences(vector& pushed, vector& popped) {
        stack s;
        int j=0;//指向poped的位置指针
        for(int i=0;i

总结

8月是在家的一个月,导师没有催我干活,也就开始刷题。也是在leetcode上成功打卡一个月的月份。也打了几场周赛(过路打卡的水平)

其中有些题目完全没有思路,有些看答案也不是很理解,先放在这里吧,等后面有空在研究研究。

在9月份期待还能够有时间坚持去刷题,在后续导师安排的qt项目上能够高质量完成界面,代码逻辑的设计,争取能够早点,高质量完成项目!

你可能感兴趣的:(力扣刷题,leetcode,算法,职场和发展)