[Go version] The thirteenth Bronze Level of Algorithm Clearance Village——Statistical problems, overflow problems, and base problems of digital mathematics problems

Write custom directory title here


The key to many mathematics-related algorithms is to find how to solve the problem in the most concise way, rather than hard calculation.

Topics in Digital Statistics

Topic: The sign of the product of array elements

Topic link: LeetCode-1822. The symbol of the product of array elements
insert image description here

Idea analysis: no real calculation is needed, just judge whether the number of negative numbers is odd or even

Complexity: time complexity O ( n ) O(n)O ( n ) , space complexityO ( 1 ) O(1)O(1)

Go code

func arraySign(nums []int) int {
    
    
    ret := 1
    for _, v := range nums {
    
    
        if v == 0 {
    
    
            return 0
        }
        if v < 0 {
    
    
            ret = -ret
        }
    }
    return ret
}

Topic: The number of factorial mantissa 0

Topic Link: LeetCode-Interview Question 16.05. Factorial Mantissa
insert image description here

Idea analysis: 2 and 5 can make up a 0, and the number of occurrences of 2 must be more than 5, so the number of occurrences of 5 can be counted

Complexity: time complexity O ( logn ) O(logn)O ( l o g n ) , space complexityO ( 1 ) O(1)O(1)

Go code

func trailingZeroes(n int) int {
    
    
    num := 0
    for n > 0 {
    
    
        n = n/5
        num += n
    }
    return num
}

Topics on overflow issues

Topic: Integer Inversion

Topic link: LeetCode-7. Integer Reversal
insert image description here

Idea analysis: divide by 10 in turn to get the remainder for value assembly, pay attention to the overflow problem

Complexity: time complexity O ( logn ) O(log n)O ( l o g n ) , space complexityO ( 1 ) O(1)O(1)

Go code

func reverse(x int) int {
    
    
    res := 0
    for x != 0 {
    
    
        // 获得末尾数字
        num := x%10
        // 判断是否大于最大整数
        if res > 0 && res > (math.MaxInt32-num)/10 {
    
    
            return 0 
        }
        // 判断是否小于最小整数
        if res <0 && res < (math.MinInt32-num)/10 {
    
    
            return 0
        }
        res = res*10 + num
        x = x/10
    }
    return res
}

Topic: String to Integer (atoi)

Topic link: LeetCode-8. String conversion integer (atoi)
insert image description here

Idea analysis: remove spaces + determine positive and negative + read value + judge overflow

Complexity: time complexity O ( n ) O(n)O ( n ) , space complexityO ( 1 ) O(1)O(1)

Go code

func myAtoi(s string) int {
    
    
    if len(s) == 0 {
    
    
        return 0
    }
    // 去除前面空格
    for i, v := range s {
    
    
        if v != ' ' {
    
    
            s = s[i:]
            break
        }
    }
    if len(s) == 0 {
    
    
        return 0
    }
    // 确定正负
    sign := 1
    if s[0] == '-' || s[0] == '+' {
    
    
        if s[0] == '-' {
    
    
            sign = -1
        }
        s = s[1:]
    }
    res, v := 0, 0
    length := len(s)
    // 读取数值
    for i:=0; i<length; i++ {
    
    
        if s[i] < '0' || s[i] > '9' {
    
    
            return res
        }
        v = int(s[i]-'0')
        // 判断越界
        if res > (math.MaxInt32-v)/10 {
    
    
            return math.MaxInt32
        }
        if res < (math.MinInt32+v)/10 {
    
    
            return math.MinInt32
        }
        res = res * 10 + sign * v
    }
    return res
}

Topic: Palindrome Number

Topic link: LeetCode-9. Palindrome number
insert image description here

Solution 1: Whether the comparison is consistent after reversing the numbers, and pay attention to the overflow problem during the reversing process

Complexity: time complexity O ( logn ) O(log n)O ( l o g n ) , space complexityO ( 1 ) O(1)O(1)

Go code

func isPalindrome(x int) bool {
    
    
    if x < 0 {
    
    
        return false
    }
    num := 0
    oldx := x
    newx := 0
    for x != 0 {
    
    
        num = x%10  //尾数
        if newx > (math.MaxInt32-num)/10 || newx < (math.MinInt32-num)/10 {
    
    
            return false
        }
        newx = newx*10 + num
        x = x/10
    }
    if newx == oldx {
    
    
        return true
    }
    return false
}

Solution 2: Check whether the comparison is consistent after only reversing half of the digits. During the comparison process, pay attention to the problem of odd digits, but do not need to consider the overflow problem (optimized solution 1)

Complexity: time complexity O ( logn ) O(log n)O ( l o g n ) , space complexityO ( 1 ) O(1)O(1)

Go code

func isPalindrome(x int) bool {
    
    
    // 负数 和 余数是0但是本身不是0 时
    if x < 0  || (x%10==0 && x != 0) {
    
    
        return false
    }
    num := 0
    // 反转一半
    for x > num {
    
    
        num = num*10 + x%10
        x = x/10
    }
    // 考虑奇位数时,忽略中间数,比如12321 中的3
    if x == num || x == num/10 {
    
    
        return true
    }
    return false
}

Hexadecimal topic

Topic: Seven base numbers

Topic link: LeetCode-504. Seven base numbers
insert image description here

Analysis of ideas: get the remainder of 7 in sequence, reverse after splicing, and pay attention to adding the minus sign when splicing

Complexity: Time complexity O ( log ∣ n ∣ ) O(log |n|)O ( l o g n ) , space complexityO ( log ∣ n ∣ ) O(log |n|)O(logn)

Go code

func convertToBase7(num int) string {
    
    
    if num == 0 {
    
    
        return "0"
    }
    sign := 1
    if num < 0 {
    
    
        sign = -1
        // 绝对值num
        num = -1 * num
    }
    res := make([]byte, 0)
    var v byte
    for num != 0 {
    
    
        // 余数依次是反转的原值
        v = byte(num%7 + '0')
        res = append(res, v)
        num = num/7
    }
    if sign < 0 {
    
    
        res = append(res, '-')
    }
    reverseArr(res, 0, len(res)-1)
    return string(res)
}
func reverseArr(arr []byte, left int, right int) {
    
    
    if left >= right {
    
    
        return
    }
    for left <= right {
    
    
        arr[left], arr[right] = arr[right], arr[left]
        left++
        right--
    }
}

Topic: convert numbers to hexadecimal

Topic link: LeetCode-405. Convert numbers to hexadecimal numbers
insert image description here

Idea analysis: Use the method &15to convert every 4-bit binary to 16-bit hexadecimal + reverse the array

Complexity: time complexity O ( 1 ) O(1)O ( 1 ) , space complexityO ( 1 ) O(1)O(1)

  • Time complexity is O ( 1 ) O(1)O ( 1 ) because the number of loop iterations is fixed, only at most 8.
  • Space complexity is O ( 1 ) O(1)O ( 1 ) , the size of the res array is fixed at 8 (because at most 8 bits are processed), so the additional space consumption is constant level.

Go code

func toHex(num int) string {
    
    
    byteArr := [16]byte{
    
    '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}
    if num == 0 {
    
    
        return "0"
    }
    res := []byte{
    
    }
    var v byte
    for i:=0;i<8;i++ {
    
    
        v = byteArr[num&15]
        res = append(res, v)
        num = num>>4
        if num == 0 {
    
    
            break
        }
    }
    reverse(res, 0, len(res)-1)
    return string(res)
}
func reverse(arr []byte, left int, right int) {
    
    
    if left >= right {
    
    
        return
    }
    for left <= right {
    
    
        arr[left], arr[right] = arr[right], arr[left]
        left++
        right--
    }
}

Topic: Convert decimal to specified base

Given a decimal number Num and the number N that needs to be converted, convert the decimal number Num to an N-ary number. Num is an integer of 32, 2<=N<=16.

Idea analysis: prepare a hexadecimal character map, divide N in turn to get the remainder, map the map to get the corresponding character, add it to the array, pay attention to the addition of the negative sign, reverse the array, and convert it to a string

Complexity: time complexity O ( lognum ) O(log num)O ( l o g n u m ) , space complexityO ( lognum ) O(log num)O(lognum)

Go code

func convert(num int, n int) string {
    
    
    byteArr := [16]byte{
    
    '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}
    if num == 0 {
    
    
        return "0"
    }
    sign := 1
    if num < 0 {
    
    
        sign = -1
        num = -num
    }
    res := []byte{
    
    }
    var v byte
    for num != 0 {
    
    
        v = byteArr[num%n]
        res = append(res, v)
        num = num/n
    }
    if sign == -1 {
    
    
        res = append(res, '-')
    }
    reverse(res, 0, len(res)-1)
    return string(res)
}
func reverse(arr []byte, left int, right int) {
    
    
    if left >= right {
    
    
        return
    }
    for left <= right {
    
    
        arr[left], arr[right] = arr[right], arr[left]
        left++
        right--
    }
}

Guess you like

Origin blog.csdn.net/trinityleo5/article/details/132397187