力扣--编程基础0到1(持续更新,一天一题)


        交替合并字符串

        两串字符串,word1 与word2 将字符串中的字符依此交替合并到新字符串中,从word1开始,此时关于字符串的长度有三种可能性,1 > 2,  1 = 2,  1 < 2。所以我们需要知道字符串的长度才能对这三种可能进行判别,因为是合并到一个字符串里面所以需要创建一个新的字符串,又知道关于string类可以进行尾插,也就是重载了 += 我们需要对字符串进行遍历以便能够进行交叉合并,在for循环中,我们将中间的判断条件更换为 i < m || i > n 这样就能满足可以进行遍历完成,所以我们进行尾插两个下标相同的字符串中的字符,并且设置一个判定条件,当 i >= n或者m的时候代表这个字符串遍历结束,由于world1先插入,所以world放在前面,之后判断第二个。

class Solution {
public:
    string mergeAlternately(string word1, string word2) 
    {
        int n = word1.size(), m = word2.size();
        string annex;
        for(int i = 0; i < m || i < n ; i++)
        {
            if(i < n)
            {
                annex += word1[i];
            }
            if(i < m)
            {
                annex += word2[i];
            }
        }
        return annex;
    }
};

        找不同 

        这个没什么可说的,最简单的方法就是利用 ASCII进行求和,之后将两个数相减,得出的ASCII值就是多出来的字母,还有暴力求解那太麻烦了,就不写了

class Solution {
public:
    char findTheDifference(string s, string t) 
    {  
        int i = 0 , j = 0;
        for(char e : s)
        {
            i += e;
        }
        for(char e : t)
        {
            j += e;
        }
        return j - i;
    }
};

        还有一种非常高效的方法就是用异或进行求解。位运算符( & | ^ )是作用于整数类型的运算对象。它是二进制位进行计算,也就是内存中的值(补码)进行计算,异或的计算规则是二进制位相同为0,相异为1。在某些情况下,char类型也可以作为异或操作符的操作数 如 char a = 'A'  , b = 'B' ; ASCII码值为65与66,而 char c = a^b; 实际上是对65和66进行异或操作。以上都是废话,如果有基础就不用看了

重点:这里解题用到了异或的几个特征

a ^ b = b ^ a。(a ^ b)^ c = a ^ (b ^ c)。a ^ a = 0。a ^ 0 = a。a ^ a ^ a = a

2 ^ 3 = 3 ^ 2。(2 ^ 3)^ 4 = 2 ^ (3 ^ 4)。2 ^ 2 = 0。2^ 0 = 2。2^ 2^ 2 = 2

而我们以"abcd"和"abcda"进行异或就是 

        a ^ b ^ c ^ a ^ b ^ c ^ a = (a^a^a)^(b^b)^(c^c) 又因为自身异或的结构为0

        (a^a^a)^(b^b)^(c^c) = (a)^0^0 = a^0 = a 这样就得出了被添加的字符

        所以解题的重点思路:利用遍历将两个字符串中的全部字符,进行异或得到多出的字符。

class Solution {
public:
    char findTheDifference(string s, string t) 
    {  
        int i = 0 ;
        for(char e : s)
        {
            i ^= e;
        }
        for(char e : t)
        {
            i ^= e;
        }
        return i;
    }
};

        找出字符中第一个匹配项的下标

        这种题是字符串匹配的题,求解方法有两种。一种是BF算法(暴力求解),一种是KMP算法,由三个大佬发明的算法,KMP算法较为复杂会单独写一篇博客,进行复习使用

        BF的实现思路:现有两个字符串,str1与str2,将str1的字符依此与str2的字符相比较,若遇见两个不相同的字符,从str1字符的现有位置跳到下一个字符上在重新进行比较,直到比较结束。代码实现就是遍历两个字符串,进行上述规则的比较。双重for循环进行遍历,如果str1的剩余字符的个数与str2的个数相同,还没有比较成功就说明不存在相同的字符串了,因为这时候str1的字符个数比str2的个数还要小就没有比较的必要了。所以遍历str1的结束条件就是下标 <=(str1的符个数-str2的字符个数)。str2正常遍历,之后就是在str2中的判断,如果第一轮遍历没有相同的,那么str1的下标就要被str2的下标多了1,第二轮多了2,所以在进行判断的时候我们str的下标就是 ( i + j ), 这样每次循环str1的下标就会向前移动一位,if判断条件是两个字符不相等使用continue跳出内部循环,str1下标加一在重新判断,如果成功则输出 i 那就是它的初始下标。

class Solution {
public:
    int strStr(string haystack, string needle) 
    {
        int n = haystack.size(), m = needle.size();
        for( int i  = 0; i <= (n - m); i++)
        {
            bool flag = true;
            for(int j = 0; j < m; j++)
            {
                if(haystack[i+j] != needle[j])
                {
                    flag = false;
                    continue;
                }
            }
            if(flag)
            {
                return i;
            }
        }
        return -1;
    }
};

        有效的字母异位词

        读题我们得到,有两个字符串均为小写,若这两个字符串出现的字符个数和次数相同那么输出true,简单来说就是,两个字符排序后字符相同那么就是字母异位词,那么就很简单了,对两个字符串进行排序如果字符串相等则输出true,否则输入false。然后首先可以对两个字符串的个数进行计算,如果不相等那么不用排序直接输入false即可。其中sort函数可以对一组数据进行升序排序,其函数原型是 void sort (RandomAccessIterator first, RandomAccessIterator last);        这道题也可以用哈希表进行解题

class Solution {
public:
    bool isAnagram(string s, string t) 
    {
        if(s.size() != t.size())
        {
            return false;
        }
        sort(s.begin(), s.end());
        sort(t.begin(), t.end());
        if(s == t)
        {
            return true;
        }
        return false;
    }
};

        移动零

                经典双指针的题,定义两个指针,同时在首元素,right为快指针,left为慢指针。当right位置的元素为0向下走,当元素不为零将right位置的元素赋值给left。双方一起向下走。等走完之后,left到right的位置就是0的位置,然后将这些位置赋值为零即可

class Solution {
public:
    void moveZeroes(vector<int>& nums) 
    {
        int right = 0, left = 0;
        while(right < nums.size() )
        {
            if(nums[right] == 0)
            {
                right++;
            }
            else
            {
           nums[left] = nums[right];
            right++;
            left++;
            }
        }
        for(left; left< nums.size(); left++)
        {
            nums[left] = 0;
        }
    }
};

         加一

        这个题的意思就是给你一个数字里面存放有数字,1,2,3将他想象成123+1 = 124变成了1,2,4.类似于这个有三种情况,上面是一种情况,还有一种情况是 1,2,9想象成129+1就变成了1,3,0.还有一种情况就是9,9,9就变成了999+1为 1,0,0,0.根据这三种情况来写代码。那么代码实现就很简单了。for循环从最后一个位置开始,如果是第一种情况,不为9对最后一个位置加1直接返回,如果最后一位为9,那么最后一位变成0,向后走一位吗,在判断是否为9不为9加+直接返回,为9举行向后走一位判断,当下标为0的时候进行最后的判断,如何还是为9那么就令他等于零,在使用insert函数,在指定位置插入一位元素,1。begin()就代表首元素。

class Solution 
{
public:
    vector<int> plusOne(vector<int>& digits) 
    {
        for(int i = digits.size() - 1; i >= 0; i--)
        {
            if(digits[i] != 9)
            {
                digits[i] += 1;
                return digits;
            }
            else
            {
                digits[i] = 0;
                if( i == 0)
                {
                    digits.insert(digits.begin(), 1);
 
                }   
            } 
        }
        return digits;
    }
};

     数组元素积的符号

        这个题没什么好说的非常简单 

class Solution {
public:
    int arraySign(vector<int>& nums) 
    {
        int sign = 1;
        for(int num : nums)
        {
            if(num == 0)
            {
                return 0;
            }
            if(num < 0)
            {
                sign = -sign;
            }
        }
        return sign;
    }
};

        判断能否形成等差数列

         首先进行判断,如果数组只有一位则构不成等差数量,然后将前一个元素和后一个元素相减得出公差,进行循环,如果是等差数列则前一位减去后一位不为公差则返回false如果循环完毕说明是等差数量返回true

class Solution {
public:
    bool canMakeArithmeticProgression(vector<int>& arr) 
    {
        sort (arr.begin(), arr.end());
        int j = arr[1] - arr[0];
        if(arr.size() < 2)
        {
            return false;
        }
        for(int i = 1; i < arr.size(); i++)
        {
            if((arr[i] - arr[i-1]) != j)
            {
                return false;
            }
        }
        return true;
    }
};

        单调数列 

         这个题利用了逻辑与,全假为假,一个for循环解决问题,设置两个bool类型,进行循环,进行判断单调递增为假,递减为加,如果一个为假,说明出现了单调增或者减,逻辑与仍为真,如果全部为假说明这个数组同时有前一个数比后一个数大或小,那么不是单调,全假为假。

class Solution {
public:
    bool isMonotonic(vector<int>& nums) 
    {
        bool m = true, n = true;
        for(int i = 1; i <nums.size(); i++ )
        {
            if(nums[i] - nums[i - 1] > 0)
            {
                m = false;  
            }
            if(nums[i] - nums[i - 1] < 0)
            {
                n = false;
            }
        }
        return m || n ;
    }
};

         最后一个单词的长度

        这题是从最后进行遍历,但是需要考虑到,如果最后一个是几个空格该怎么办,所有加入了bool类型如果遍历到字符了bool类型变成正确,如果没有遍历到字符那就是错误,并且只有bool是正确且当前元素为空格才能说明题最后一个字母遍历完成了

class Solution {
public:
    int lengthOfLastWord(string s) 
    {
        char n = ' ';
        int m = 0;
        bool flag = false;
        for(int i = s.size()-1; i >= 0; i--)
        {
            if(s[i] == ' ' && flag)
            {
                return m;
            }
            if(s[i] != n)
            {
                flag = true;
                m++;
            }
            
        }
        return m;
    }
};

        机器人能否返回原点

        这个题很简单,机器人上下左右移动,要想返回原地上下左右的次数必须一样才行,所以定义两个变量,上下一个变量为0向上++ 向下-- ,左右同理。当两个变量为零。则说明返回了原点。

class Solution {
public:
    bool judgeCircle(string moves) 
    {
        int x = 0, y = 0;
        for(const char& e : moves)
        {
            if( e == 'R')
            {
                x++;
            }
            else if (e == 'L')
            {
                x--;
            }
            else if (e == 'U')
            {
                y++;
            }
            else if (e == 'D')
            {
                y--;
            }
        }
        return x == 0 && y == 0;
    }
};

        在区间范围内统计奇数数目

 

        while循环,当low > high的时候说明区间的树取完了。如果 low % 2== 1是奇函数,直接加2就可以得到下一个奇函数,设置n代表奇函数的个数,如果是偶函数加一就是奇函数了。 

class Solution {
public:
    int countOdds(int low, int high) 
    {
        int n = 0;
        while(low <= high)
        {
            if(low % 2 == 1)
            {
                low += 2;
                n++;
            }
            else if(low % 2 == 0)
            {
                low ++;
            }
        }
        return n;
    }
};

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值