2024.8.17 Python,简单题,二分法,Counter的用法

1. 数组异或操作

给你两个整数,n 和 start 。
数组 nums 定义为:nums[i] = start + 2*i(下标从 0 开始)且 n == nums.length 。
请返回 nums 中所有元素按位异或(XOR)后得到的结果。

这个题本来是很简单的,但是我做的不好,我的错误代码如下:

class Solution:
    def xorOperation(self, n: int, start: int) -> int:
        ans=0
        nums=[]
        for i in range(n):
            nums[i]=start+2*i
            ans=ans^nums[i]
        return ans

此代码错误,原因是因为我定义了nums=[],此时如果直接写进去东西,是写不进的,所以解决办法如下
1.避免使用列表:

class Solution:
    def xorOperation(self, n: int, start: int) -> int:
        ans = 0
        for i in range(n):
            ans ^= start + 2 * i
        return ans

直接异或等,就是自等,这样就避免使用列表
2.使用动态处理

class Solution:
    def xorOperation(self, n: int, start: int) -> int:
    	ans=0
    	nums=[]
    	for i in range(n):
    		nums.append(start+2*i)
    		ans=ans^nums[i]
    	return ans

3.使用动态创建列表,这个其实是我最开始想到的处理,这样的处理是最直观的。

class Solution:
	def xorOperation(self,n:int,start:int)->int:
		ans=0
		nums=[0]*n
		for i in range (n):
			nums[i]=start+2*i
			ans=ans^nums[i]
		return ans

这个题很简单,但是学习这个题目的是为了培养一个良好的编程习惯和思路,毕竟我是半路子直接开始看题的,所以规范化必须得注意,思路对了结果细节上做不到就很尴尬。

2.给定一个非负整数 num,反复将各个位上的数字相加,直到结果为一位数。返回这个结果。

示例 1:
输入: num = 38
输出: 2
解释: 各位相加的过程为:
38 --> 3 + 8 --> 11
11 --> 1 + 1 --> 2
由于 2 是一位数,所以返回 2。
这个题我也做错了,原因是去做回归调用的时候,return设置的不好,导致最后算完以后只输出了第一层的return,我的错误代码如下:

class Solution:
    def addDigits(self, num: int) -> int:
        num=str(num)
        n=len(num)
        sum=0
        if n>=2:
            for i in range(n):
                sum=int(num[i])+sum
        if sum>=10:
            sol=Solution()
            sol.addDigits(sum)
        return sum

***重看:***想法是好的,但是实际操作的时候逻辑思考还是缺少了一点,chat教我,说在self.addDigits这里可以直接return

class Solution:
    def addDigits(self, num: int) -> int:
        num=str(num)
        n=len(num)
        sum=0
        if n>=2:
            for i in range(n):
                sum=int(num[i])+sum
        if sum>=10:
            return self.addDigits(sum)
        return sum

这样子修改以后就非常完美了。

3.创建一个0矩阵,不借用numpy库

transposed = [[0] * m for _ in range(n)]
这个的含义是,创建了一个n行m列的0矩阵
m, n = len(matrix), len(matrix[0])
这个是,m行n列

4.分割字符串的最大得分

给你一个由若干 0 和 1 组成的字符串 s ,请你计算并返回将该字符串分割成两个 非空 子字符串(即 左 子字符串和 右 子字符串)所能获得的最大得分。「分割字符串的得分」为 左 子字符串中 0 的数量加上 右 子字符串中 1 的数量。
示例 1:
输入:s = “011101”
输出:5
解释:
将字符串 s 划分为两个非空子字符串的可行方案有:
左子字符串 = “0” 且 右子字符串 = “11101”,得分 = 1 + 4 = 5
左子字符串 = “01” 且 右子字符串 = “1101”,得分 = 1 + 3 = 4
左子字符串 = “011” 且 右子字符串 = “101”,得分 = 1 + 2 = 3
左子字符串 = “0111” 且 右子字符串 = “01”,得分 = 1 + 1 = 2
左子字符串 = “01110” 且 右子字符串 = “1”,得分 = 2 + 1 = 3
我写的暴力解

class Solution:
    def maxScore(self, s: str) -> int:
        n=len(s)
        ans,score=0,0
        for i in range (1,n):
            for j in range(0,i):
                if s[j]=='0':
                    score+=1
            for k in range(i,n):
                if s[k]=='1':
                    score+=1
            ans=max(ans,score)
            score=0
        return ans        

简单解法:

class Solution:
    def maxScore(self, s: str) -> int:
        return max(s[:i].count('0') + s[i:].count('1') for i in range(1, len(s)))

没啥好说的,有时候这些奇奇怪怪的函数就是很方便,但是你就是不知道代码是等效的,可以用上面的代码解释下面的代码。这个题是一个很好的,关于指针指向数字中间分隔的例子,其中指针为(1,n)左边为(0,i)右边为(i,n)

5.统计范围内的元音字符串数

给你一个下标从 0 开始的字符串数组 words 和两个整数:left 和 right 。
如果字符串以元音字母开头并以元音字母结尾,那么该字符串就是一个 元音字符串 ,其中元音字母是 ‘a’、‘e’、‘i’、‘o’、‘u’ 。
返回 words[i] 是元音字符串的数目,其中 i 在闭区间 [left, right] 内。
示例 1:
输入:words = [“are”,“amy”,“u”], left = 0, right = 2
输出:2
解释:

  • “are” 是一个元音字符串,因为它以 ‘a’ 开头并以 ‘e’ 结尾。
  • “amy” 不是元音字符串,因为它没有以元音字母结尾。
  • “u” 是一个元音字符串,因为它以 ‘u’ 开头并以 ‘u’ 结尾。
    在上述范围中的元音字符串数目为 2 。
class Solution:
    def vowelStrings(self, words: List[str], left: int, right: int) -> int:
        vowel=set('aeiou')
        ans=0
        for i in range (left,right+1):
            if words[i][0] in vowel and words[i][-1] in vowel:
                ans+=1
        return ans

这个代码中需要注意的是,
1.set之后,vowel是一个集合而非列表,只能在这里面查到底有没有这个东西,如果要把单词存成字符串那就要用vowels = set([‘abc’, ‘der’, ‘ios’]),这样的代码
2.right这里需要加一,因为会漏,right得取到,
3.word[i][-1]指的是倒数第一个,所以这个表达很好。

6.山脉数组的峰顶索引

给定一个长度为 n 的整数 山脉 数组 arr ,其中的值递增到一个 峰值元素 然后递减。
返回峰值元素的下标。
你必须设计并实现时间复杂度为 O(log(n)) 的解决方案。
示例 1:
输入:arr = [0,1,0]
输出:1
示例 2:
输入:arr = [0,2,1,0]
输出:1


所以二分法的逻辑就是,缩小范围,我将从代码最上面从下面一步一步分析
1.left,right这里,他们的起步都是不从0和n-1开始,我最开始在想,0和n-1怎么覆盖到呢, 其实是后续while循环的时候,最后一次循环能让指针指回来
2.while left<=right是循环条件,也就是说当left>right 的时候循环就最后一次了
3.mid=(left+right)//2这里的地板除其实很有意思,我不在乎小数点那里,不管。
4.if arr[mid] > arr[mid + 1]:左大就先赋值,然后右边范围为mid-1
为什么在 if 里要赋值 ans,而在 else 里不需要?
if 块:当 arr[mid] > arr[mid + 1] 时,mid 有可能是峰值,因此将 ans 更新为当前的 mid,以备后续使用。即使后续发现真正的峰值在 mid 的左边,ans 也可以保留这个可能的峰值位置。
else 块:当 arr[mid] <= arr[mid + 1] 时,mid 一定不是峰值,峰值必然在 mid 的右边。因此,不需要更新 ans,继续搜索右边部分即可。
5.else就只左边范围为mid+1
6.最后return ans

7.给定两个字符串 s 和 t ,它们只包含小写字母。

字符串 t 由字符串 s 随机重排,然后在随机位置添加一个字母。
请找出在 t 中被添加的字母。

示例 1:
输入:s = “abcd”, t = “abcde”
输出:“e”
解释:‘e’ 是那个被添加的字母。
示例 2:
输入:s = “”, t = “y”
输出:“y”
这个题还是我第一次过了初试然后没过总的测试的代码,很烦,原因在于,我以为题目是出现了一个额外的字母,未出现的字母,他其实是说,s=aabb,t=aabbb的话,就输出b,所以他的测试代码里没有这个可能性,我就没懂他啥意思,也就是说以后出现这种情况,要考虑有没有可能是因为思路出问题了,测试用例和题目描述是被包含关系。

***新知识:***Counter是 collections 模块中的一个类,专门用于统计可哈希对象(例如字符串中的字符)的出现次数。它返回一个字典,键是对象,值是它们的计数

from collections import Counter
s = "abcd"
t = "abcde"
print(Counter(s))  # 输出: Counter({'a': 1, 'b': 1, 'c': 1, 'd': 1})
print(Counter(t))  # 输出: Counter({'a': 1, 'b': 1, 'c': 1, 'd': 1, 'e': 1})

那么这个题就有:

diff = Counter(t) - Counter(s)
print(diff)  								# 输出: Counter({'e': 1})
diff_list = list(Counter(t) - Counter(s)) 	# 强制转为列表
print(diff_list)  							# 输出: ['e']
return list(Counter(t) - Counter(s))[0]		# 列表第一个字母,键
  • 27
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
二分法是一种常用的数值分析方法,用于求解非线性方程的根。在Python中,可以通过编写函数来实现二分法求解非线性方程的根。以下是一个简单的例子: ```python def bisection(f, a, b, tol=1e-6): """ 二分法求解非线性方程的根 :param f: 非线性方程 :param a: 区间左端点 :param b: 区间右端点 :param tol: 精度要求 :return: 根 """ fa = f(a) fb = f(b) if fa * fb > 0: raise ValueError("f(a)和f(b)符号相同,无法使用二分法求解根") while b - a > tol: c = (a + b) / 2 fc = f(c) if fc == 0: return c elif fa * fc < 0: b = c fb = fc else: a = c fa = fc return (a + b) / 2 ``` 在上述代码中,bisection函数接受四个参数:非线性方程f、区间左端点a、区间右端点b和精度要求tol。函数首先计算区间左右端点的函数值fa和fb,如果它们的符号相同,则无法使用二分法求解根,抛出ValueError异常。然后,函数进入一个循环,直到区间长度小于精度要求tol为止。在每次循环中,函数计算区间中点c的函数值fc,如果fc等于0,则直接返回c。否则,如果fa和fc的符号不同,则根在区间[a, c]中,将b赋值为c,fb赋值为fc;否则,根在区间[c, b]中,将a赋值为c,fa赋值为fc。最后,函数返回区间中点的值。 以下是一个使用bisection函数求解非线性方程的例子: ```python import math def f(x): return x ** 3 - 2 * x - 5 root = bisection(f, 1, 3) print("根为:", root) # 输出:根为: 2.0945510864257812 ``` 在上述代码中,我们定义了一个非线性方程f(x) = x^3 - 2x - 5,并使用bisection函数求解其在区间[1, 3]内的根。最后,我们输出了求解得到的根。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值