LeetCode-【数学】数学在解题中的技巧

1. 不使用变量交换两个数

交换两个数

# 异或
a ^ b = c
c ^ b = a
a ^ c = b
numbers[0] ^= numbers[1];
numbers[1] ^= numbers[0];
numbers[0] ^= numbers[1];

# 加减
A = A+B
B = A-B
A = A-B
numbers[1]=numbers[0]+numbers[1];
numbers[0]=numbers[1]-numbers[0];
numbers[1]=numbers[1]-numbers[0];

2.位运算巧妙题解

136. 只出现一次的数字1

(此题解利用了异或的性质)

def singleNumber(self, nums):
    """
    :type nums: List[int]
    :rtype: int
    """
    res = 0
    for i in nums:
        res^=i
    return res

137. 只出现一次的数字 II

(此题解跳出了题目本身,可以推广到在多个重复n次的数字中找到唯一出现一次的数)

int singleNumber(vector<int>& nums) {
        int value=0;
        for(int i=0;i<32;i++)
        {
            int sum=0;
            for(int j=0;j<nums.size();j++)
            {
                if((nums[j]>>i)&1)
                {
                    sum+=1;
                }
            }
            value+=((sum%3)<<i);
        }
        return value;
    }

260. 只出现一次的数字 III

(此题解的核心在于分组,因为相同元素,在所有bit位是一致的,而不同的数字,必然有某一个bit位存在差异,而找到所有值异或结果后(即可获取存在差异的bit位位置),只需根据存在差异的那一个bit位,将两个不同的数字分到不同的组,即可求出结果。)

vector<int> singleNumber(vector<int>& nums) {
        vector<int> t(2,0);
        int value_xor=nums[0]^nums[1];
        for(int i=2;i<nums.size();i++)
        {
            value_xor^=nums[i];
        }
        int index=0;
        for(int i=0;i<32;i++)
        {
            if((value_xor>>i)&1)
            {
                index=i;
                break;
            }
        }
        for(int i=0;i<nums.size();i++)
        {
            if((nums[i]>>index)&1)
            {
                t[0]^=nums[i];
            }
            else
            {
                t[1]^=nums[i];
            }
        }
        return t; 
    }

3.求最大值

面试题 16.07. 最大数值

int(((a+b)+abs(a-b))/2)

4.快速幂

面试题16. 数值的整数次方

原理如下:

    def myPow(self, x, n):
        """
        :type x: float
        :type n: int
        :rtype: float
        """
        if x==0:
            return 0
        res = 1
        if n<0:
            x,n = 1/x,-n
        #x=3,n=6
        #n=6(0x110),res=1,x=3*3 -> n=3,x=9
        # n=3(0x11),res=9,x=9*9 -> n=1,x=81
        #  n=1(0x1),res=729,x=81*81 -> n=0,x=6561
        while n>0:
            if n&1==1:
                res*=x
            x*=x
            n/=2
        return res

2094. 找出 3 位偶数

暴力遍历:

class Solution:
    def findEvenNumbers(self, digits: List[int]) -> List[int]:
        ret = set()
        L = len(digits)
        for i in range(L):
            if digits[i] == 0:
                continue
            for j in range(L):
                for k in range(L):
                    t = digits[i]*100+digits[j]*10+digits[k]
                    if i!=j and i!=k and j!=k and t%2==0:
                        ret.add(t)
        return sorted(list(ret))

偶数顺序遍历:

class Solution:
    def findEvenNumbers(self, digits: List[int]) -> List[int]:
        dict_ = {}
        ret = []
        for i in digits:
            dict_[i] = dict_.get(i,0)+1

        for i in range(100,999,2):
            t = 0
            t_ = {}
            flag = True
            j = i
            while j>0:
                t = j%10
                t_[t] = t_.get(t,0)+1
                if t_[t]>dict_.get(t,0):
                    flag = False
                    break
                j//=10
            if flag:
                ret.append(i)
        return ret

2575. 找出字符串的可整除数组

证明结论:每次向后增加一位时, 我们只考虑前面的余数部分, 这样是不会影响结果的。

class Solution:
    def divisibilityArray(self, word: str, m: int) -> List[int]:
        ans, x = [], 0
        for d in map(int, word):
            x = (x * 10 + d) % m
            ans.append(int(x == 0))
        return ans

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值