leetcode 莽夫办法

LeetCode

截断句子

https://leetcode.cn/problems/truncate-sentence/description/

  • 句子 是一个单词列表,列表中的单词之间用单个空格隔开,且不存在前导或尾随空格。每个单词仅由大小写英文字母组成(不含标点符号)。
  • 例如,“Hello World”、“HELLO” 和 “hello world hello world” 都是句子。
    给你一个句子 s​​​​​​ 和一个整数 k​​​​​​ ,请你将 s​​ 截断 ​,​​​使截断后的句子仅含 前 k​​​​​​ 个单词。返回 截断 s​​​​​​ 后得到的句子
  • 提示:
    1 <= s.length <= 500
    k 的取值范围是 [1, s 中单词的数目]
    s 仅由大小写英文字母和空格组成
    s 中的单词之间由单个空格隔开
    不存在前导或尾随空格

代码实现:

class Solution {
public:
    string truncateSentence(string s, int k) {
        
        if(s.size() <1 || s.size() >500) {
            return string();
        }
        string result;
        int index = 0,index_s = 0;
        while(index_s < s.size()) {
            char data = s.at(index_s); 
            index_s += 1;

            if(data == ' ') {
                index += 1;
                if(index == k) {
                    return result;
                } else {
                    result.push_back(data);
                }
            } else {
                result.push_back(data);

                if(index_s == s.size()) {
                	assert(index+1 == k);
                    return result;
                }
            }

        }
        return result;
    }
};

下一个更大元素 III

https://leetcode.cn/problems/next-greater-element-iii

  • 给你一个正整数 n ,请你找出符合条件的最小整数,其由重新排列 n 中存在的每位数字组成,并且其值大于 n 。如果不存在这样的正整数,则返回 -1 。
  • 注意 ,返回的整数应当是一个 32 位整数 ,如果存在满足题意的答案,但不是 32 位整数 ,同样返回 -1 。

思路:

  • 将正整数转为一维数组先进行 评比找出第一个比之大的队列,然后评判是否越界,若没越界则进行还原整数返回。

代码实现:

  •   int nextGreaterElement(int n) {
          if(n < 1 || n > (2147483648 -1))
              return -1;
          
          vector<int> max_v = {2,1,4,7,4,8,3,6,4,7};
          std::vector<int> vNum;
          while(n>0) {
              vNum.push_back(n%10);
              n = n / 10;
          }
    
          // 第一层遍历
          for(int i=0;i<vNum.size();i++) {
              
              // 第二层遍历,找到比之大的,同时余下的进行排序
              for(int j=0;j<i;j++) {
                  if(vNum.at(j)>vNum.at(i)) {
    
                      int tmp = vNum.at(j);
                      vNum.at(j) = vNum.at(i);
                      vNum.at(i) = tmp;
                      
                      sort(vNum.begin(),vNum.begin()+i,greater<int>());
    
                      if(vNum.size() == max_v.size()) {
                          for(int i = vNum.size()-1;i>=0;i--) {
                              int max_ds = max_v.at(vNum.size()-1-i);
                              if(vNum.at(i) > max_ds) {         
                                  return -1;
                              } else if(vNum.at(i) < max_ds){
                                  break;
                              }
                          }
                      }
    
                      long int result = 0,ssd = 1;
                      for(int k = 0;k < vNum.size();k++) {
                          result += vNum.at(k) * ssd;
                          if(k+1 != vNum.size())
                              ssd = ssd * 10;
                      }
                      return result;
                  }
              }
          }
          return -1;
      }
    

寻找两个整数序列的中位数

https://leetcode.cn/problems/median-of-two-sorted-arrays/description/

  • 给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。

  • 算法的时间复杂度应该为 O(log (m+n)) 。

思路:

  • 这个题比较简单,先确定中位数下标(奇数还是偶数要注意),遍历两个序列,基于小值一次相加直到下标,然后计算得到。
double findMedianSortedArrays(const std::vector<int>& nums1,const std::vector<int>& nums2) {

    const int size_total = nums1.size() + nums2.size();

    std::deque<int> mind_index;

    if(size_total % 2 == 1) {
      mind_index.push_back((size_total+1)/2);
    } else {
      mind_index.push_back(size_total/2);
      mind_index.push_back((size_total/2+1));
    }

    double result = 0;  // 结果

    int index_final = 0; // 已找个数
    int nums1_index = 0,nums2_index = 0; // 1,2小标

    while(nums1_index < nums1.size() || nums2_index < nums2.size()) {

      int this_num = -1;

      if(nums1_index < nums1.size() && nums2_index < nums2.size()) {
        if(nums1.at(nums1_index) < nums2.at(nums2_index)) {
          this_num = nums1.at(nums1_index++);
        } else {
          this_num = nums2.at(nums2_index++);
        }
      } else if(nums1_index < nums1.size() ) {

        this_num = nums1.at(nums1_index++);

      } else {
        this_num = nums2.at(nums2_index++);
      }

      if( (++index_final) == mind_index.front())  {
        result +=(this_num);
        mind_index.pop_front();
      }
      if(mind_index.empty()) {
        break;
      }
    }

    if(size_total % 2 == 0) {
      result /= 2;
    }

    return result;
}

对称二叉树

给你一个二叉树的根节点 root , 检查它是否轴对称。

思路:

  • 一个递归,本题我使用了前中序遍历和后中序遍历进行比较,同时加了树深度,因为有个案例树深度不用还过不了。
bool isSymmetric(TreeNode* root) {

    // 中序遍历改为前序遍历
    if(root != nullptr) {
        auto front_bl = FrontBL(root->left,1);
        auto back_bl = BackBL(root->right,1);
        if(front_bl.size() != back_bl.size()) {
            return false;
        }
        std::cout<<"size:"<<front_bl.size()<<std::endl;
        for(int i=0;i<front_bl.size();i++) {

            if(front_bl.at(i).first != back_bl.at(i).first || 
               front_bl.at(i).second != back_bl.at(i).second) {

                return false;
            }
         }
    }
    return true;
}

std::vector<pair<int,int>> FrontBL(TreeNode* node,int depth) {
    std::vector<pair<int,int>> result;
    if(node != nullptr) {
        auto left_result = FrontBL(node->left,depth+1);
        auto right_result = FrontBL(node->right,depth+1);
        result = left_result;
        result.push_back(make_pair(node->val,depth));
        result.insert(result.end(),right_result.begin(),                         right_result.end());
    }else {
        result.push_back(make_pair(-1,depth));
    }
    return result;
}
std::vector<pair<int,int>> BackBL(TreeNode* node,int depth) {
    std::vector<pair<int,int>> result;
    if(node != nullptr) {
        auto left_result = BackBL(node->left,depth+1);
        auto right_result = BackBL(node->right,depth+1);
        result = right_result;
        result.push_back(std::make_pair(node->val,depth));
        result.insert(result.end(),left_result.begin(),                         left_result.end());
    }else {
        result.push_back(make_pair(-1,depth));
    }
    return result;
}

在每个树行中找最大值

https://leetcode.cn/problems/find-largest-value-in-each-tree-row/description/

  • 给定一棵二叉树的根节点 root ,请找出该二叉树中每一层的最大值。

思路:

  • 一个map记录该树每层最大值,然后将其最大值返回即可,树递归最简单
/**
 * 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:
    vector<int> largestValues(TreeNode* root) {

        vector<int> result;
        GetMaxDepth(root,0);
        for(const auto& data: m_max_depth_) {
            result.push_back(data.second);
        }
        return result;
    }
    std::map<int,int> m_max_depth_;

    void GetMaxDepth(TreeNode* root,int depth) {

        if(root == nullptr) {
            return ;
        }

        if(m_max_depth_.count(depth)) {
            if(m_max_depth_.at(depth) < root->val) {
                m_max_depth_.at(depth) = root->val;
            }
        } else {
            m_max_depth_.emplace(depth,root->val);
        }
        GetMaxDepth(root->left,depth+1);
        GetMaxDepth(root->right,depth+1);
    }
};

运动员和训练师的最大匹配数

网址

  • 给你一个下标从 0 开始的整数数组 players ,其中 players[i] 表示第 i 名运动员的 能力 值,同时给你一个下标从 0 开始的整数数组 trainers ,其中 trainers[j] 表示第 j 名训练师的 训练能力值 。
  • 如果第 i 名运动员的能力值 小于等于 第 j 名训练师的能力值,那么第 i 名运动员可以 匹配 第 j 名训练师。除此以外,每名运动员至多可以匹配一位训练师,每位训练师最多可以匹配一位运动员。
  • 请你返回满足上述要求 players 和 trainers 的 最大 匹配数。

Code:

class Solution {
public:
    int matchPlayersAndTrainers(vector<int>& players, vector<int>& trainers) {
        sort(players.begin(),players.end());
        sort(trainers.begin(),trainers.end());

        int result = 0;
        int trainer_index = 0;
        for(int i=0;i< players.size();i++) {
            while(trainer_index < trainers.size()) {
                if(players[i] <= trainers[trainer_index]) {
                    trainer_index ++;
                    result ++;
                    break;
                }
                trainer_index ++;
            }

            if(trainer_index >= trainers.size()) {
                break;
            }
        }
        return result;
    }
};

牛客

比较版本号

比较版本号

牛客项目发布项目版本时会有版本号,比如1.02.11,2.14.4等等

  • 现在给你2个版本号version1和version2,请你比较他们的大小
    版本号是由修订号组成,修订号与修订号之间由一个"."连接。1个修订号可能有多位数字组成,修订可能包含前导0,且是合法的。例如,1.02.11,0.1,0.2都是合法的版本号
    每个版本号至少包含1个修订号。
    修订号从左到右编号,下标从0开始,最左边的修订号下标为0,下一个修订号下标为1,以此类推。

比较规则:

  • 一. 比较版本号时,请按从左到右的顺序依次比较它们的修订号。比较修订号时,只需比较忽略任何前导零后的整数值。比如"0.1"和"0.01"的版本号是相等的
  • 二. 如果版本号没有指定某个下标处的修订号,则该修订号视为0。例如,“1.1"的版本号小于"1.1.1”。因为"1.1"的版本号相当于"1.1.0",第3位修订号的下标为0,小于1
  • 三. version1 > version2 返回1,如果 version1 < version2 返回-1,不然返回0.

数据范围:

  • 1 <= version1.length, version2.length <= 10001<=version1.length,version2.length<=1000
    version1 和 version2 的修订号不会超过int的表达范围,即不超过 32 位整数 的范围

进阶: 空间复杂度 O(1)O(1) , 时间复杂度 O(n)O(n)

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 比较版本号
     * @param version1 string字符串 
     * @param version2 string字符串 
     * @return int整型
     */
    // write code here
int compare(std::string version1, std::string version2 ) {
    if(version1.empty() || version2.empty()) {
        return 0;
    }

    int v1_index = 0,v2_index = 0;
    std::string v1_str,v2_str;
    bool v1_dot=false,v2_dot=false;

    while(1) {

        if(!v1_dot && v1_index < version1.size()) {
            if(version1[v1_index] == '.') {
                v1_dot = true;
            } else {
                if(v1_str.empty() && version1[v1_index] == '0') {
                } else {
                    v1_str.push_back(version1[v1_index]);
                }
            }
            v1_index ++;

        }
        if(v1_index == version1.size()) {
            v1_dot = true;
        }

        if(!v2_dot && v2_index < version2.size()) {

            if(version2[v2_index] == '.') {
                v2_dot = true;
            } else {
                if(v2_str.empty() && version2[v2_index]=='0'){

                } else{
                    v2_str.push_back(version2[v2_index]);
                }
            }
            v2_index++;
        }            
        if(v2_index == version2.size()) {
            v2_dot = true;
        } 

        if(v1_dot && v2_dot) {
            std::cout<<"dot1: "<<v1_str<<std::endl;
            std::cout<<"dot2: "<<v2_str<<std::endl;

            if(v1_str == v2_str) {
                v1_str.clear();
                v2_str.clear();
                v1_dot = false;
                v2_dot = false;
            } else {
                std::cout<<"no empty(): "<<std::endl;

                if(v1_str.empty() && v2_str.empty()) {
                    v1_str.clear();
                    v2_str.clear();
                    v1_dot = false;
                    v2_dot = false;
                }

                if(!v1_str.empty() && !v2_str.empty()) {
                    if(v1_str == v2_str) {}

                    if(v1_str.size()> v2_str.size()) {return 1;}
                    if(v1_str.size() < v2_str.size()) {return -1;}

                    if(v1_str > v2_str){
                        return 1;
                    } else { 
                        return -1;
                    }
                } else if(v1_str.empty()) {
                    return -1;
                } else {
                    return 1;
                }
            }
        }
        if(version1.size() == v1_index && version2.size() == v2_index ) {
            break;
        }
    }
    return 0;
    }
};

End

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值