题解《算法零基础100讲》(第18讲) 线性枚举 - 统计法入门(java版)

Posted 敲代码的xiaolang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题解《算法零基础100讲》(第18讲) 线性枚举 - 统计法入门(java版)相关的知识,希望对你有一定的参考价值。

😁算法小白欢迎加入此社区:https://bbs.csdn.net/forums/hero?category=0
由英雄大佬带领的抱团学算法队伍,从0开始,期待你的加入
🥳


本博文是对此文章习题所作的题解,如有不足,请多指教:https://blog.csdn.net/WhereIsHeroFrom/article/details/120875708

今日题解:
第一题:https://leetcode-cn.com/problems/find-numbers-with-even-number-of-digits/

重拳出击,直接遍历,然后再判断位数

class Solution {
    public int findNumbers(int[] nums) {
        int i, answer=0;
        for(i=0; i<nums.length; i++){
            int number = test(nums[i]);
            if(number % 2 == 0){
                answer++;
            }
        }
        return answer;
    }
    public int test(int num){
        int count = 0;
		while (num > 0) {
			num /= 10;
			count++;
		}
		return count;
    }
}


第二题:https://leetcode-cn.com/problems/single-element-in-a-sorted-array/

直接顺着题意去写,如果里面有一个数或者两个数,直接出结果,我们需要单独判断开头的数字和结尾的那两个数字,因为这里比较的特殊,他们没有前一个元素或者后一个元素。当数更多的时候,我们就直接遍历,然后判断目前位置的前一个数字和后一个数字与它是否是一样的。

class Solution {
    public int singleNonDuplicate(int[] nums) {
        int i;
        if(nums.length==1){
            return nums[0];
        }
        if(nums[0]!=nums[1]){
            return nums[0];
        }
        if(nums[nums.length-1]!=nums[nums.length-1-1]){
            return nums[nums.length-1];
        }
        for(i=1; i < nums.length-1; i++){
            if((nums[i]!=nums[i-1]) && (nums[i]!=nums[i+1])){
                return nums[i];
            }
        }
        return 0;
    }
}

第三题:https://leetcode-cn.com/problems/diao-zheng-shu-zu-shun-xu-shi-qi-shu-wei-yu-ou-shu-qian-mian-lcof/

直接去遍历,提前准备一个下标去承接后面来的新的数组元素。

class Solution {
    public int[] exchange(int[] nums) {
        int i, temp, number = 0;
        for(i=0; i<nums.length; i++){
            if(nums[i]%2!=0){
                temp = nums[i];
                nums[i] = nums[number];
                nums[number] = temp;
                number++;
            }
        }
        return nums;
    }
}

第四题:https://leetcode-cn.com/problems/find-the-middle-index-in-array/

直接遍历,左边的那部分直接求和,然后再对右半部分求和,如果两者的和一样,那么就代表符合条件,我们每一次循环之后,要把统计左边和右边的和的变量清零,方便一下次统计。

class Solution {
    public int findMiddleIndex(int[] nums) {
        int sum = 0;
        int sum1 = 0;
        int i,j;
        for(i=0; i<nums.length; i++){
            for(j=0; j < i; j++){
                sum = sum + nums[j];
            }
            for(j=i+1; j < nums.length; j++){
                sum1 =sum1 + nums[j];
            }
            if(sum == sum1){
                return i;
            }
            sum = 0;
            sum1 = 0;
        }
        return -1;
    }
}


第五题:https://leetcode-cn.com/problems/find-pivot-index/

和上面一道题一样,直接重拳出击。

class Solution {
    public int pivotIndex(int[] nums) {
        int sum = 0;
        int sum1 = 0;
        int i,j;
        for(i=0; i<nums.length; i++){
            for(j=0;j<i;j++){
                sum = sum + nums[j];
            }
            for(j=i+1; j<nums.length; j++){
                sum1 =sum1 + nums[j];
            }
            if(sum == sum1){
                return i;
            }
            sum = 0;
            sum1 = 0;
        }
        return -1;
    }
}


第六题:https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array/

题目要求在原数组修改,所以不能使用上面题目所用到的去重方法,这里使用nums[n+1] = nums[i];
n++;
length++;

达到去重的效果。

class Solution {
    public int removeDuplicates(int[] nums) {
        int n = 0,i;
        int length = 1;
    for (i = 1; i < nums.length; i++) {
        if(nums[i] != nums[n]){
            nums[n+1]=nums[i];
            n++;
            length++;
        }
    }
    return length;
    }
}


第七题:https://leetcode-cn.com/problems/binary-prefix-divisible-by-5/

这道题没有想出来,参考了此篇博文才搞懂题意,刚开始误把其当成要转换为10进制去处理。参考博文:https://www.cnblogs.com/xiaochuan94/p/11167822.html

核心在于下图,新的二进制数是在前一次二进制数的基础上左移一位得到的,只需要我们判断每次新组成的二进制数能否被5整除:

class Solution {
    public List<Boolean> prefixesDivBy5(int[] nums) {
        List<Boolean> answer = new ArrayList<Boolean>();
        int num = 0, i;
        for (i=0; i < nums.length; i++) {
            num = num*2 + nums[i];
            num = num % 5;
            answer.add(num == 0);
        }
        return answer;
    }
}

第八题:https://leetcode-cn.com/problems/smallest-integer-divisible-by-k/

这道题刚开始的时候没有什么思路,参考了一下大佬们的解法,我们先去判断这个数是否可以被2或者是否可以被5整除,因为我们的 2、4、6、8、5都是无法得到尾数是1的情况,所以只有1、3、7、9可以得到我们想要的结果。所以先判断是否可以被2或者5整除,然后我们进入下面代码里面的while循环,我们如果 x % K != 0 ,我们举一个例子,我们让 K 为 3,那么我们的x开始为 1,然后 x进行 x = x*10+1,此时的x为11,我们再让它去和K做运算,此时依然符合循环的条件,那么此时 x 是 111,此时再进入到循环的判断条件的时候,111%3==0,跳出循环,我们也就得到了所需要的number的值。

class Solution {
    public int smallestRepunitDivByK(int K) {
        if (K % 2 == 0 || K % 5 == 0) {
            return -1;
        }
        int x = 1;
        int number = 1;
        while (x % K != 0) {
            x = x % K;
            x = x * 10 + 1;
            number++;
        }
        return number;
    }
}


第九题:https://leetcode-cn.com/problems/longer-contiguous-segments-of-ones-than-zeros/

和上面的直接遍历中间位置的左半部分和右半部分是一样的,其实也就是枚举而已,我们可以遍历整个字符串,如果此时的字符是 1,那么对应的数字加加,同理为 0 的时候,负责统计 0 的个数变量也进行加加,但是需要注意的是,我们判断为 1 的情况的时候,结束这种情况的时候,我们需要把代表统计0的个数的那个变量进行清零,因为下一次又要重新进行计数。同理统计0的时候,也要把代表1的个数的变量给清零。

class Solution {
    public boolean checkZeroOnes(String s) {
        int len = s.length();
        int n_1 = 0, number_1 = 0, n_0 = 0, number_0 = 0, i;
        for(i = 0; i < len; i++){
            if(s.charAt(i) == '1'){
                n_1++;
                number_1 = Math.max(n_1,number_1);
                n_0 = 0;
            }else{
                n_0++;
                number_0 = Math.max(n_0,number_0);
                n_1 = 0;
            }
        }
        if(number_0 >= number_1){
            return false;
        }else{
            return true;
        }
    }
}

有问题欢迎留言,欢迎加入“万人千题”社区,在这里一起努力。

(今日立冬,今日大雪,下图拍的很好看🤗,有亮点,虽然不是我拍的~🥳)

以上是关于题解《算法零基础100讲》(第18讲) 线性枚举 - 统计法入门(java版)的主要内容,如果未能解决你的问题,请参考以下文章

《算法零基础100讲》(第17讲) 线性枚举 - 最值算法

题解《算法零基础100讲》(第10讲) 因子分解和枚举(java版)

《算法零基础》第18讲:线性枚举- 统计法入门

《算法零基础100讲》(第32讲) 多维枚举 - 进阶

《算法零基础100讲》(第31讲) 多维枚举 - 入门

《算法零基础100讲》(第51讲) 二进制枚举子集