• Leetcode题解(十)


    29、Divide Two Integers

    题目

    题目要求不用乘除和取模运算,实现两个整数相除;

    我的第一想法就是把除法变成减法来做,这也是最初除法的定义,其实现代码如下:

     1 class Solution {
     2 public:
     3     int divide(int dividend, int divisor) {
     4         if(1 == divisor)
     5             return dividend;
     6         if (-1 == divisor)
     7             return 0-dividend;
     8         
     9         bool flag = false;
    10 
    11         if((dividend<0&&divisor>0))
    12         {
    13             dividend = 0-dividend;
    14             flag = true;
    15         }
    16         else if(dividend>0&&divisor<0)
    17         {
    18             divisor = 0-divisor;
    19             flag = true;
    20         }
    21 
    22         dividend = abs(dividend);
    23         divisor = abs(divisor);
    24         
    25 
    26         int result = 0;
    27         while (dividend >=divisor)
    28         {
    29             dividend -= divisor;
    30             result++;
    31         }
    32         if(flag)
    33             result = 0 - result;
    34 
    35         return result;
    36 
    37     }
    38 };

    看似没什么问题,但是其效率是不高的,比如被除数很大,而除数很小的时候,while循环会执行很多次,导致其效率不高,因此需要想想其他的办法解决该问题;既然直接做减法会超时,那姑且只能想移位操作了,因为移位操作是比较高效的操作,能够快速得到想要结果。如果是移位操作,应该如何下手呢?任何一个整数可以表示成以2的幂为底的一组基的线性组合,即num=a_0*2^0+a_1*2^1+a_2*2^2+...+a_n*2^n,在做除法时,dividend/divisor = num,变换一下就可以写成这样dividend = divisor*(a_0*2^0+a_1*2^1+a_2*2^2+...+a_n*2^n);因此先让divisor左移n位,然后用dividend减去这个数,剩下的结果继续用同样的方法求解n-1,代码如下:

     1 class Solution {
     2 public:
     3    int divide(int dividend, int divisor) {
     4         // Note: The Solution object is instantiated only once.
     5         long long a = abs((double)dividend);
     6         long long b = abs((double)divisor);
     7         long long res = 0;
     8         while(a >= b)
     9         {
    10             long long c = b;
    11             for(int i = 0; a >= c; i++, c <<=1)
    12             {
    13                 a -= c;
    14                 res += 1<<i;
    15             }
    16         }
    17         
    18         
    19         if((dividend ^ divisor) >> 31) 
    20             res = 0-res;
    21         if(res >= 2147483647)
    22             return 2147483647;
    23         else
    24             return res;
    25         
    26     }
    27 };

    ---------------------------------------------------------------------------------------------分割线--------------------------------------------------------------------------------

    30、Substring with Concatenation of All Words

    题目:

    首先得弄懂题目的意思,这道题看了很久才弄明白题目意思:也就是说,给定一个字符串数组,数组中的字符串不管以什么顺序拼接在一起,得到新的字符串new,然后在s中查找new在s中第一次出现的下标,题目给的例子可以拼接成foobar或者barfoo,然后判断其起始下标分别为9,0;

    按照上面说的,可以做n!次拼接,然后通过kmp算法判断在s中出现的下标,但是这种方式的效率太低,得想想其他方法,降低算法时间复杂度;

    想了一会,想到了一个解决该问题的方法:依次遍历字符串s,第i(i从0开始)轮遍历时,也就是从s的s[i]开始,依次截取子字符串,截取长度为一个word的长度,然后判断words数组中是否有当前子字符串,如果没有,i++,如果存在,再从i+word.length处截取子字符串,以此类推;再判断子字符串是否存在时,可以通过一个map统计每个word出现的次数,遍历时,出现一个word,则对应次数加1,具体看代码实现:

     1 class Solution {
     2 public:
     3     vector<int> findSubstring(string S, vector<string> &L) {
     4         int l_size = L.size();
     5         
     6         if (l_size <= 0) {
     7             return vector<int>();
     8         }
     9         
    10         vector<int> result;
    11         map<string, int> word_count;
    12         int word_size = L[0].size();
    13         int i, j;
    14         
    15         for (i = 0; i < l_size; ++i) {
    16             ++word_count[L[i]];
    17         }
    18         
    19         map<string, int> counting;
    20         
    21         for (i = 0; i <= (int)S.length() - (l_size * word_size); ++i) {
    22             counting.clear();
    23             
    24             for (j = 0; j < l_size; ++j) {
    25                 string word = S.substr(i + j * word_size, word_size);
    26                 
    27                 if (word_count.find(word) != word_count.end()) {
    28                     ++counting[word];
    29                     
    30                     if (counting[word] > word_count[word]) {
    31                         break;
    32                     }
    33                 }
    34                 else {
    35                     break;
    36                 }
    37             }
    38             
    39             if (j == l_size) {
    40                 result.push_back(i);
    41             }
    42         }
    43         
    44         return result;
    45     }
    46 };
  • 相关阅读:
    realsense SDK debug
    网络
    JVM基础系列第11讲:JVM参数之堆栈空间配置
    图片一句话木马简单制作方法
    RocketMQ(四):生产者消息数据写入实现细节
    RocketMQ(三):broker启动逻辑
    发现一个新的技术网站 https://dotnet9.com/
    【最新】解决Github网页上图片显示失败的问题
    c++入门
    Newtonsoft.Json json.net 可以丢弃了,微软发布了 System.Text.Json 适用于.net 4.6.1 +,后悔了,建议.net5+项目使用
  • 原文地址:https://www.cnblogs.com/LCCRNblog/p/5037250.html
Copyright © 2020-2023  润新知