这里主要是和编程思想有关的习题
大多来自于牛客与LeetCode,总结如下

习题

1. 阶乘尾数中0的个数

例: 3! = 6;故而尾数0的个数为0个
    5! = 120;故而尾数中0的个数为1个

2.旋转数组

要求三种方法以及O(1)的空间复杂度(原地算法)
例如: 1,2,3,4,5  移动次数 2
    第一次 5,1,2,3,4
    第二次 4,5,1,2,3  结果值

答案

1.阶乘尾数中0的个数

由于偶数乘任何数都得偶数
首先阶乘中获得的结果除去尾数的0也必定为偶数
    例 : 1*2*3*4*5 = (2*5)  * 1*3*4    
    并且1-9做乘法运算只有5乘偶数才能得到0
其次5与任何偶数作乘获得0的十位为1,2,3,4 -->(2,4,6,8)
    例 : 5! = (1) * 1*3*4     得到一个尾数0
而且分解的偶数必定多于5的个数
故而求阶乘尾数0的个数实际就变成了阶乘每一项因式分解能得到的5的个数
    将n/5就获得了所有因式分解中含有一个5的数的第一个5
    继续除5就获得了因式分解中含有两个5的数的第二个5
    将这些结果加起来就得到了所有5的个数
            5  2*5  3*5  4*5  5*5  6*5     ...
    n/5     1    1    1     1      1        1    ...
    n/25    0   0    0     0      1        0    ...
    ..        0    0    0     0      0        0    ...
具体代码如下 :
1
2
3
4
5
6
public int trailingZeros(int n){
int result = 0;
while((n /= 5) > 0)
result += n;
return result;
}

旋转数组

首先移动次数等于数组长度,就复原了
    那么移动次数为k%数组长度,若为0则不移动
然后移动k个位置其实就是将前k个元素移动到后面
思路一 : 
    利用反转,数组反转两次就得到了原数组
    那么先反转一次,前面的元素都到了后面
    而后面的元素都到前面
    然后拿后面的k个元素反转,以及前面的长度-k个元素反转
    就得到了符合条件的数组

思路二 :
    利用进制运算,进制为数组的长度
    将第一个元素移动到它应该在的位置,再将下一个以同样的规律移动
    一直循环就能得到符合条件的数组,但是要注意k是长度的约数的情况
        原理证明:
            利用的反证法,一开始索引为0且一直加k对长度取余
            得到的余数集第一个重复的值必定为0
            先从0开始 后面的值开始在0的后面 同样的操作必定是0先
        如果是约数,会在长度次数之前获得重复值
            长度8,k=2   8/2=4次  0..2..4..8(8 % 8=0)
            这时候就需要对0...k-1作操作即可交换整个数组所有位置
        如果不是约数,由于第一个重复值必定是第一个索引
            直接操作长度次数即可