笔试刷题必备------ 数学问题

笔试刷题必备------ 数学问题

  • 笔试刷题必备------ 数学问题
    • Fizz Buzz
    • 计数质数
    • 3的幂
    • 罗马数字转整数
    • 直线上最多的点数
    • 缺失数字
    • 分数到小数
    • 位1的个数
    • 颠倒二进制位
    • 阶乘后的零
    • 快乐数
    • Excel表列序号
    • Pow(x, n)
    • x 的平方根
    • 两数相除
    • 多数元素
    • 逆波兰表达式求值

笔试刷题必备------ 数学问题

Fizz Buzz

写一个程序,输出从 1 到 n 数字的字符串表示。

1. 如果 n 是3的倍数,输出“Fizz”;

2. 如果 n 是5的倍数,输出“Buzz”;

3.如果 n 同时是3和5的倍数,输出 “FizzBuzz”。

示例:

n = 15,

返回:
[
“1”,
“2”,
“Fizz”,
“4”,
“Buzz”,
“Fizz”,
“7”,
“8”,
“Fizz”,
“Buzz”,
“11”,
“Fizz”,
“13”,
“14”,
“FizzBuzz”
]

class Solution(object):
    def fizz_buzz(self,n):
        res = []
        for i in range(1,n+1):
            if i % 3 == 0 and i % 5 == 0:
                res.append("FizzBuzz")
            elif i % 3 == 0:
                res.append("Fizz")
            elif i % 5 == 0:
                res.append("Buzz")
            else:
                res.append(str(i))
        return res

if __name__ == "__main__":
    solu = Solution()
    print(solu.fizz_buzz(15))

计数质数

暴力算法(会超时)

import math
class Solution(object):
	def count_primes(self,n):
		res = 0
		for i in range(n+1):
			if self.is_prime(i):
				res += 1
		return res

	def is_prime(self,num):
		if num <= 3:
			return num < 1
		sqrt = int(math.sqrt(num))
		for i in range(2,sqrt+1):
			if num % i == 0:
				return False
		return True


if __name__ == "__main__":
    solu = Solution()
    print(solu.count_primes(15))

3的幂

给定一个整数,写一个函数来判断它是否是 3 的幂次方。

示例 1:

输入: 27
输出: true

示例 2:

输入: 0
输出: false

示例 3:

输入: 9
输出: true

示例 4:

输入: 45
输出: false

进阶:
你能不使用循环或者递归来完成本题吗?

循环:

class Solution(object):
	def isPowerOfThree(self,n):
		while n > 0:
			if n % 3 == 0:
				n /=3
			else:
				break
		return True if n == 1 else False

不使用循环或者递归


#不使用循环或者递归
class Solution2():
    def isPowerOfThree(self,n):
        # 3^19=1162261467是小于2^31最大的3的倍数
        return n > 0 and 3**19 % n == 0

罗马数字转整数

罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。

字符          数值
I             1
V             5
X             10
L             50
C             100
D             500
M             1000

例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。

通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:

I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。
给定一个罗马数字,将其转换成整数。输入确保在 1 到 3999 的范围内。

示例 1:

输入: "III"
输出: 3

示例 2:

输入: "IV"
输出: 4

示例 3:

输入: "IX"
输出: 9

示例 4:

输入: "LVIII"
输出: 58

解释: L = 50, V= 5, III = 3.
示例 5:

输入: "MCMXCIV"
输出: 1994

解释: M = 1000, CM = 900, XC = 90, IV = 4.

class Solution(object):
	def roman_to_int(self,s):
		d = {'I':1,'V':5,'X':10,'L':50,'C':100,'D':500,'M':1000}
		res = 0
		i = 0
		while i < len(s)-1:
			if d[s[i]] >= d[s[i+1]]:
				res += d[s[i]]
				i += 1
			else:
				temp = d[s[i+1]] - d[s[i]]
				res += temp
				i += 2
		if i == len(s)-1:
			res += d[s[i]]
		return res if 1 <= res <= 3999 else False		

直线上最多的点数

给定一个二维平面,平面上有 n 个点,求最多有多少个点在同一条直线上。

示例 1:

输入: [[1,1],[2,2],[3,3]]
输出: 3
解释:
^
|
|        o
|     o
|  o  
+------------->
0  1  2  3  4

示例 2:

输入: [[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]]
输出: 4
解释:
^
|
|  o
|     o        o
|        o
|  o        o
+------------------->
0  1  2  3  4  5  6

穷举,算出每个点和其他各个点的斜率(若两个点和同一个点的斜率相同,那么这三个点在同一条直线上),计算不同斜率点的个数(别忘了把当前点加上),还要注意和当前点重合的,以及斜率为无穷的。

在这里插入代码片

缺失数字

给定一个包含 0, 1, 2, …, n 中 n 个数的序列,找出 0 … n 中没有出现在序列中的那个数。

示例 1:

输入: [3,0,1]
输出: 2

示例 2:

输入: [9,6,4,2,3,5,7,0,1]
输出: 8

说明:
你的算法应具有线性时间复杂度。你能否仅使用额外常数空间来实现?
方法一:利用枚举(Python特性)

class Solution(object):
    def missingNumber(self,nums):
        nums = sorted(nums)
        for i,j in enumerate(nums):

            if i != j:
                return i

方法二:利用等差数列求和

class Solution2(object):
    def missingNumber(self,nums):
        return ((1+len(nums))*len(nums)//2)-sum(nums)

方法三:^位运算

class Solution(object):
    def missingNumber(self,nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        bit = 0
        for i,j in enumerate(nums):

            bit ^= i ^ j

        return bit^len(nums)

分数到小数

给定两个整数,分别表示分数的分子 numerator 和分母 denominator,以字符串形式返回小数。

如果小数部分为循环小数,则将循环的部分括在括号内。

示例 1:

输入: numerator = 1, denominator = 2
输出: "0.5"

示例 2:

输入: numerator = 2, denominator = 1
输出: "2"

示例 3:

输入: numerator = 2, denominator = 3
输出: "0.(6)"
class Solution(object):
    def fractionToDecimal(self, numerator, denominator):
        """
        :type numerator: int
        :type denominator: int
        :rtype: str
        """
        if numerator == 0:
            return '0'
        elif denominator == 0:
            return ''
        else:
            isNegative = (numerator < 0) ^ (denominator < 0)
            numerator = abs(numerator)
            denominator = abs(denominator)
            res = ''
            res += '-' if isNegative else ''
            res += str(numerator//denominator)
            numerator %= denominator
            if numerator == 0:
                return res
            else:
                res +='.'
                dic = {}
                while numerator:
                    if numerator in dic:
                        start = dic[numerator]
                        end = len(res)
                        res = res[:start] + '(' + res[start:end] + ')'
                        return res
                    dic[numerator] = len(res)
                    res += str(numerator*10//denominator)
                    numerator = numerator*10%denominator
                return res



if __name__ == "__main__":
    solu = Solution()
    print(solu.fractionToDecimal(1,3))

位1的个数

编写一个函数,输入是一个无符号整数,返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为汉明重量)。

示例 1:

输入:00000000000000000000000000001011
输出:3
解释:输入的二进制串 00000000000000000000000000001011 中,共有三位为 '1'。

示例 2:

输入:00000000000000000000000010000000
输出:1
解释:输入的二进制串 00000000000000000000000010000000 中,共有一位为 '1'。

示例 3:

输入:11111111111111111111111111111101
输出:31
解释:输入的二进制串 11111111111111111111111111111101 中,共有 31 位为 '1'。
class Solution(object):
    def hammingWeight(self, n):
        if n == 0:
            return 0
        sum = 0
        while n > 0:
            sum += n&1
            #依次右移
            n = n >> 1

        return sum

if __name__ == "__main__":
    solu = Solution()
    print(solu.hammingWeight(0o0000000000000000000000000001011))

颠倒二进制位

颠倒给定的 32 位无符号整数的二进制位。

示例 1:

输入: 00000010100101000001111010011100
输出: 00111001011110000010100101000000
解释: 输入的二进制串 00000010100101000001111010011100 表示无符号整数 43261596,
  因此返回 964176192,其二进制表示形式为 00111001011110000010100101000000。

示例 2:

输入:11111111111111111111111111111101
输出:10111111111111111111111111111111
解释:输入的二进制串 11111111111111111111111111111101 表示无符号整数 4294967293,
  因此返回 3221225471 其二进制表示形式为 10101111110010110010011101101001。

提示:

请注意,在某些语言(如 Java)中,没有无符号整数类型。在这种情况下,输入和输出都将被指定为有符号整数类型,并且不应影响您的实现,因为无论整数是有符号的还是无符号的,其内部的二进制表示形式都是相同的。
在 Java 中,编译器使用二进制补码记法来表示有符号整数。因此,在上面的 示例 2 中,输入表示有符号整数 -3,输出表示有符号整数 -1073741825。

进阶:
如果多次调用这个函数,你将如何优化你的算法?

class Solution:
    # @param n, an integer
    # @return an integer
    def reverseBits(self, n):
        res = 0
        count = 32
        while count:
            res <<= 1 # 取出 n 的最低位数加到 res 中
            res += n&1
            n >>= 1
            count -= 1
        return res

阶乘后的零

给定一个整数 n,返回 n! 结果尾数中零的数量。

示例 1:

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

示例 2:

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

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

class Solution(object):
	def trailingZeroes(self,n):
		r = 0
		while n >= 5:
			n = n//5
			r += n
		return r

快乐数

编写一个算法来判断一个数是不是“快乐数”。

一个“快乐数”定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是无限循环但始终变不到 1。如果可以变为 1,那么这个数就是快乐数。

示例:

输入: 19
输出: true
解释: 
1^2 + 9^2 = 82
8^2 + 2^2 = 68
6^2 + 8^2 = 100
1^2 + 0^2 + 0^2 = 111
class Solution(object):
    def is_happy(self,n):
        temp = []
        while True:
            n = self.get_add(n)
            if n == 1:
                return True

            #出现死循环就退出,并返回False
            elif n in temp:
                return False

            else:
                temp.append(n)


    def get_add(self,n):
        res = 0
        while n != 0:
            g = n %10
            res += g**2
            n = n//10
        return res

if __name__ == "__main__":
    solu = Solution()

    print(solu.is_happy(19))


Excel表列序号

给定一个Excel表格中的列名称,返回其相应的列序号。

例如,

A -> 1
B -> 2
C -> 3
...
Z -> 26
AA -> 27
AB -> 28 
...

示例 1:

输入: "A"
输出: 1

示例 2:

输入: "AB"
输出: 28

示例 3:

输入: "ZY"
输出: 701
class Solution(object):
    def titleToNumber(self,s):
        res = 0
        for letter in s:
            res += res*26 + ord(letter) - ord('A')+1
        return res

if __name__ == "__main__":
    solu = Solution()
    print(solu.titleToNumber("ZY"))

Pow(x, n)

实现 pow(x, n) ,即计算 x 的 n 次幂函数。

示例 1:

输入: 2.00000, 10
输出: 1024.00000

示例 2:

输入: 2.10000, 3
输出: 9.26100

示例 3:

输入: 2.00000, -2
输出: 0.25000
解释: 2-2 = 1/22 = 1/4 = 0.25

说明:

-100.0 < x < 100.0
n 是 32 位有符号整数,其数值范围是 [−231, 231 − 1] 。

class Solution(object):
    def myPow(self,x,n):
        if not n:
            return 1
        if n < 0:
            return 1/self.myPow(x,-n)
        if not n & 1:
            return self.myPow(x * x, n >> 1)

        else:
            return self.myPow(x,n-1)*x

if __name__ == "__main__":
    solu =Solution()
    print(solu.myPow(2.1,3))

x 的平方根

实现 int sqrt(int x) 函数。

计算并返回 x 的平方根,其中 x 是非负整数。

由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。

示例 1:

输入: 4
输出: 2

示例 2:

输入: 8
输出: 2

说明: 8 的平方根是 2.82842…,
由于返回类型是整数,小数部分将被舍去。

class Solution(object):
    def mySqrt(self, x):
        """
        :type x: int
        :rtype: int
        """
        if x <= 1:
            return x
        else:
            left = 1
            right = x
            mid = (left+right)//2
            while (right-left) >=2:
                if mid*mid == x:
                    return mid
                elif mid*mid < x:
                    left = mid
                    mid = (left+right)//2
                else:
                    right = mid
                    mid  = (left+right)//2
            return mid

两数相除

给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。

返回被除数 dividend 除以除数 divisor 得到的商。

示例 1:

输入: dividend = 10, divisor = 3
输出: 3

示例 2:

输入: dividend = 7, divisor = -3
输出: -2

说明:

被除数和除数均为 32 位有符号整数。
除数不为 0。
假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−231, 231 − 1]。本题中,如果除法结果溢出,则返回 231 − 1。

class Solution:
    def divide(self, dividend, divisor):
        result = 0
        pointer = 0
        if (dividend >= 0 and divisor < 0) or (divisor >= 0 and dividend < 0):
            pointer = 0
        else:
            pointer = 1
        dividend = abs(dividend)
        divisor = abs(divisor)
        while dividend >= divisor:
            temp, i = divisor, 1
            while dividend >= temp:
                dividend -= temp
                result += i
                i <<= 1
                temp <<= 1
        if pointer == 0: result = -result
        return min(max(result, -2 ** 31), 2 ** 31 - 1)

多数元素

给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。

你可以假设数组是非空的,并且给定的数组总是存在多数元素。

示例 1:

输入: [3,2,3]
输出: 3

示例 2:

输入: [2,2,1,1,1,2,2]
输出: 2	

排序法:

class Solution(object):
    def majorityElement(self, nums):
        nums = sorted(nums)
        return nums[len(nums)//2]

投票法:

class Solution(object):
    def majorityElement(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        count = 0
        candi = 0
        for i in nums:
            if i == candi:
                count += 1
            else:
                if count ==0:
                    candi = i
                    count = 1
                else:
                    count -= 1
        return candi

逆波兰表达式求值

根据逆波兰表示法,求表达式的值。

有效的运算符包括 +, -, *, / 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。

说明:

整数除法只保留整数部分。
给定逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。
示例 1:

输入: ["2", "1", "+", "3", "*"]
输出: 9

解释: ((2 + 1) * 3) = 9
示例 2:

输入: ["4", "13", "5", "/", "+"]
输出: 6

解释: (4 + (13 / 5)) = 6
示例 3:

输入: ["10", "6", "9", "3", "+", "-11", "*", "/", "*", "17", "+", "5", "+"]
输出: 22

解释:
((10 * (6 / ((9 + 3) * -11))) + 17) + 5
= ((10 * (6 / (12 * -11))) + 17) + 5
= ((10 * (6 / -132)) + 17) + 5
= ((10 * 0) + 17) + 5
= (0 + 17) + 5
= 17 + 5
= 22


class Solution:
    def evalRPN(self, tokens):
        """
        :type tokens: List[str]
        :rtype: int
        """
        import operator
        stack = []
        ops = { "+": operator.add, "-": operator.sub, "*": operator.mul, "/": operator.truediv}
        for char in tokens:
            if char in ops:
                t1 = int(stack.pop())
                t2 = int(stack.pop())
                stack.append(ops[char](t2,t1))
            else:
                stack.append(char)
        return int(stack.pop())


if __name__ == "__main__":
    solu = Solution()
    tokens = ["4", "13", "5", "/", "+"]

    solu  =Solution()
    print(solu.evalRPN(tokens))

你可能感兴趣的:(Avery的笔试题复习总结)