Sword refers to the second edition of Offer: the number of occurrences of 1 in 1~n integers, 51. The reverse order pair in the array, 56 - II. The number of occurrences of numbers in the array II

43. The number of occurrences of 1 in 1~n integers

Topic : Input an integer n, find the number of occurrences of 1 in the decimal representation of n integers from 1 to n.
For example, if you input 12, the integers from 1 to 12 include 1, 10, 11 and 12, and 1 appears 5 times in total.
Example 1:
Input: n=12
Output: 5

**Thinking analysis:** Process each digit of n separately, calculate the number of 1s in each digit, and then add the number of 1s in all digits. Specifically, first judge whether n is 0, if n is 0, return 0 directly. Then process each digit in turn from low to high, and calculate the number of 1s in the current digit. If the number of the current digit is less than 1, the number of 1 is the current digit of the high digit, that is, highbit; if the number of the current digit is equal to 1, the number of 1 is the current digit of the high digit + the low digit + 1, that is, the highbit +low+1; if the number of the current digit is greater than 1, the number of 1 is (high+1)*bit, that is, the high digit plus one multiplied by the current digit. Finally, add up the number of 1s in all digits to get the final result.
Time complexity: Each digit of n needs to be processed, so the time complexity is O ( log ⁡ n ) O(\log n)O(logn ) .
Space complexity: Only a constant level of extra space needs to be used, so the space complexity isO ( 1 ) O(1)O(1)

class Solution {
    
    
    public int countDigitOne(int n) {
    
    
        if (n == 0) {
    
     // 如果n为0,直接返回0
            return 0;
        }
        long bit = 1; // bit表示当前处理的位数
        long cur = n / bit % 10; // cur表示当前处理的数字
        long low = n % bit; // low表示当前位数以下的数字
        long high = n / bit / 10; // high表示当前位数以上的数字
        long res = 0; // res表示1的个数
        while (bit <= n) {
    
     // 当位数小于等于n的位数时,继续处理
            if (cur < 1) {
    
     // 如果当前位数的数字小于1,1的个数为high*bit
                res += high * bit;
            } else if (cur == 1) {
    
     // 如果当前位数的数字等于1,1的个数为high*bit+low+1
                res += high * bit + low + 1;
            } else {
    
     // 如果当前位数的数字大于1,1的个数为(high+1)*bit
                res += (high + 1) * bit;
            }

            bit *= 10; // 处理下一位数
            cur = n / bit % 10;
            low = n % bit;
            high = n / bit / 10;
        }

        return (int) res; // 返回1的个数

    }
}

51. Reversed pairs in an array

Question : Two numbers in an array, if the previous number is greater than the following number, then the two numbers form a reverse pair. Given an array, find the total number of reversed pairs in the array.
Example 1:
Input: [7,5,6,4]
Output: 5

Idea analysis: In the process of merging and sorting, each time two sorted sub-arrays are merged, the number of reversed pairs needs to be counted. In specific implementation, during the merging process, if the number in the left half is greater than or equal to the number in the right half, it means that the remaining numbers in the left half are greater than the number in the right half, so you can directly count the number of reversed pairs.
Time complexity: The time complexity of merge sorting is O(nlogn), and in the process of merge sorting, each time two sorted sub-arrays are merged, all elements need to be traversed once, so the time complexity of merging is also O (nlogn). So the total time complexity is O(nlogn).
Space complexity: Merge sort needs to use a temporary array to store the data during the merging process, so the space complexity is O(n).

class Solution {
    
    
    int res = 0; // 记录逆序对数量

    public int reversePairs(int[] nums) {
    
    
        if (nums == null || nums.length == 0) {
    
    
            return 0;
        }

        mergeSort(nums, 0, nums.length - 1); // 归并排序
        return res; // 返回逆序对数量
    }

    private void mergeSort(int[] nums, int l, int r) {
    
    
        if (l >= r) {
    
    
            return;
        }

        int mid = (r - l) / 2 + l; // 计算中间位置
        mergeSort(nums, l, mid); // 对左半段进行归并排序
        mergeSort(nums, mid + 1, r); // 对右半段进行归并排序
        merge(nums, l, mid, r); // 合并左右两个有序的子数组
    }

    private void merge(int[] nums, int l, int mid, int r) {
    
    
        int i = l; // 左半段的起始位置
        int j = mid + 1; // 右半段的起始位置
        int[] temp = new int[r - l + 1]; // 用于存储合并过程中的数据
        int index = 0; // 临时数组的下标
        while (i <= mid && j <= r) {
    
     // 合并左右两个有序的子数组
            if (nums[i] <= nums[j]) {
    
     // 如果左半段的数小于右半段的数
                temp[index++] = nums[i++]; // 将左半段的数加入临时数组中
            } else {
    
     // 如果左半段的数大于等于右半段的数
                res += mid - i + 1; // 统计逆序对数量
                temp[index++] = nums[j++]; // 将右半段的数加入临时数组中
            }
        }

        // 将剩余的元素复制到临时数组中
        while (i <= mid) {
    
    
            temp[index++] = nums[i++];
        }

        while (j <= r) {
    
    
            temp[index++] = nums[j++];
        }

        // 将临时数组中的元素复制回原数组中
        index = 0;
        for (i = l; i <= r; i++) {
    
    
            nums[i] = temp[index++];
        }
    }
}

56 - II. Number of occurrences of numbers in an array II

Question : In an array nums, except for one number that only appears once, other numbers appear three times. Please find the number that appears only once.
Example 1:
Input: nums = [3,4,3,3]
Output: 4

Idea analysis: For each digit, count the number of occurrences of all numbers in that digit, and then take modulo 3 to get the value of the digit that appears once in that digit. Finally, the values ​​of all bits are combined to obtain the final result.
The time complexity is O(nk), where n is the number of numbers and k is the number of binary digits, because all numbers and all digits need to be traversed.
The space complexity is O(k), because an array of length k needs to be used to record the number of occurrences of each number in each bit.

class Solution {
    
    
    public int singleNumber(int[] nums) {
    
    
        if(nums == null || nums.length == 0){
    
    
            return -1;
        }

        int res = 0; // 用于存储最终结果
        int bit = 1; // 用于表示当前位的值,从最低位开始
        int[] count = new int[32]; // 用于记录所有数字在当前位上出现的次数
        for(int i = 0; i < 32; i++){
    
     // 遍历所有位
            for(int j = 0; j < nums.length; j++){
    
     // 遍历所有数字
                if((nums[j] & bit) != 0){
    
     // 如果当前数字在当前位上为1
                    count[i]++; // 记录出现次数
                }
            }
            count[i] %= 3; // 对3取模,得到出现1次的数字在当前位上的值
            res += bit * count[i]; // 将当前位的值加入最终结果
            bit <<= 1; // 判断下一位
        }

        return res; // 返回最终结果
    }
}

Guess you like

Origin blog.csdn.net/weixin_51405802/article/details/130362725