初识Leetcode----学习(十九)【阶乘后的零、旋转数组】

阶乘后的零

示例 1:

输入: 3
输出: 0
解释: 3! = 6, 尾数中没有零。

示例 2:

输入: 5
输出: 1
解释: 5! = 120, 尾数中有 1 个零.

说明: 你算法的时间复杂度应为 O(log n) 

1.计算阶乘之后零的个数,也即计算阶乘中包含5的个数,对于25、125这样的可能包含多个5,需要注意一下:

class Solution {
public:
    int trailingZeroes(int n) {
        int cnt = 0;
        while (n)
        {
            cnt += n/5;
            n /= 5;
        }
        return cnt;
    }
};

2.利用递归,将上述思路写成递归:

class Solution {
public:
    int trailingZeroes(int n) {
        return n == 0 ? 0 : (n/5) + trailingZeroes(n/5);
    }
};

旋转数组

给定一个数组,将数组中的元素向右移动 个位置,其中 是非负数。

示例 1:

输入: [1,2,3,4,5,6,7]k = 3
输出: [5,6,7,1,2,3,4]
解释:
向右旋转 1 步: [7,1,2,3,4,5,6]
向右旋转 2 步: [6,7,1,2,3,4,5]
向右旋转 3 步: [5,6,7,1,2,3,4]

示例 2:

输入: [-1,-100,3,99]k = 2
输出: [3,99,-1,-100]
解释: 
向右旋转 1 步: [99,-1,-100,3]
向右旋转 2 步: [3,99,-1,-100]

说明:

  • 尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。
  • 要求使用空间复杂度为 O(1) 的原地算法。

1.遍历数组,从0遍历到n-k(n为数组长度),将首部元素插入到容器尾部,并删除首部元素,依次遍历,实现旋转数组:

具体实现:

输入数组:[1,2,3,4,5,6,7], k = 3

第一轮:数组[2,3,4,5,6,7,1] 

第二轮:数组[3,4,5,6,7,1,2]

第三轮:数组[4,5,6,7,1,2,3]

class Solution {
public:
    void rotate(vector<int>& nums, int k) {
        if (nums.empty() || (k %= nums.size()) == 0)  //如果容器为空或旋转步数大于数组长度返回空
            return;
        int n = nums.size();
        for (int i = 0; i < n-k; ++i)
        {
            nums.push_back(nums[0]);         //将数组首元素插入到容器尾
            nums.erase(nums.begin());        //删除容器首元素
        }
    }
};

2.调用标准库算法reverse,首先将数组中旋转步数之外的元素进行翻转,然后把旋转步数之内的元素进行翻转,最后将前两步得到的数组整体翻转,得到旋转数组:

具体实现:

输入数组:[1,2,3,4,5,6,7]

第一步:数组:[4,3,2,1,5,6,7]

第二步:数组:[4,3,2,1,7,6,5]

第三步:数组:[5,6,7,1,2,3,4]

class Solution {
public:
    void rotate(vector<int>& nums, int k) {
        if (nums.empty() || (k %= nums.size()) == 0)
            return;
        int n = nums.size();
        reverse(nums.begin(), nums.begin() + n-k);   //翻转前半部分
        reverse(nums.begin() + n-k, nums.end());      //翻转后半部分
        reverse(nums.begin(), nums.end());           //翻转整个数组
    }
};

3.用数组初始化得到一个新数组t,保存当前元素,然后通过映射将原元素值存入数组的对应位置中(t中i对应nums中(i + k) %n):

具体实现:

输入数组:[1,2,3,4,5,6,7]

例:i = 0时,对应存入数组(i + k) % n位置,即第3位

按照这样的映射关系得到旋转数组

class Solution {
public:
    void rotate(vector<int>& nums, int k) {
        if (nums.empty() || (k %= nums.size()) == 0)
            return;
        vector<int> t = nums;   //保存原数组元素
        int n = nums.size();
        for (int i = 0; i < n; ++i)
        {
            nums[(i + k) % n] = t[i];   //将元素通过映射存入原数组
        }
    }
};

猜你喜欢

转载自blog.csdn.net/qq_38790716/article/details/83472893