topic26:删除有序数组中的重复项
题目描述:给你一个 升序排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。
思路:删除原列表时,列表长度会发生变化,从而影响元素下标,发生索引错误,为了解决这个问题,可以使用倒序循环的方式遍历列表,从最后一个元素遍历到第一个元素,如果当前元素与前一个元素相同,则删除当前元素。不会影响到后续元素的下标
def removeDuplicates(nums):
length=len(nums)
for i in range(length-1,0,-1):
if nums[i]==nums[i-1]:
nums.pop(i)
else:
temp+=1
return nums
topic27:移除元素
题目描述:
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
思路:与上题相同,倒序遍历删除,最后返回列表长度
def removeElement(nums,val):
length=len(nums)
for i in range(length-1,-1,-1): #倒序遍历
if nums[i]==val:
nums.pop(i)
return nums
topic28:找出字符串中第一个匹配项的下标
题目描述:给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle 不是 haystack 的一部分,则返回 -1 。
思路:类似于kmp数组匹配
def strStr(haystack,needle):
if needle not in haystack:
return -1
else:
length1=len(haystack)
length2=len(needle)
for i in range(0,length1-length2+1): #确保两字符串长度相等时可以匹配
if needle[0:]==haystack[i:i+length2]:
return i
topic29:两数相除
题目描述:给你两个整数,被除数 dividend 和除数 divisor。将两数相除,要求 不使用 乘法、除法和取余运算。整数除法应该向零截断,也就是截去(truncate)其小数部分。例如,8.345 将被截断为 8 ,-2.7335 将被截断至 -2 。返回被除数 dividend 除以除数 divisor 得到的 商 。
思路1:暴力法,用加法逐渐逼近,但是会超时
def divide(dividend,divisor):
divid1=abs(dividend)
divisor1=abs(divisor)
if (dividend>0 and divisor<0) or (dividend<0 and divisor>0):
for i in range(0,divid1+1):
if divid1<divisor1:
if i>-pow(2,31) and i<pow(2,31)-1:
return -i
elif i>pow(2,31)-1:
return pow(2,31)-1
else:
return -pow(2,31)
else:
divid1-=divisor1
else:
for i in range(0,divid1+1):
if divid1<divisor1:
if i>-pow(2,31) and i<pow(2,31)-1:
return i
elif i>pow(2,31)-1:
return pow(2,31)-1
else:
return -pow(2,31)
else:
divid1-=divisor1
思路二:移位运算
思路:计算机乘除法原理——移位,时间复杂度O(logn)
def divide(dividend, divisor):
# 首先判断除数是否为0,如果为0则应该抛出异常或者返回None
if divisor == 0:
raise ZeroDivisionError("division by zero")
# 将被除数和除数都转换为非负整数
divid1 = abs(dividend)
divisor1 = abs(divisor)
# 如果被除数小于除数,则直接返回0
if divid1 < divisor1:
return 0
result = 0 # 记录结果
# 如果两个数异号,则最终结果为负数
if (dividend > 0 and divisor < 0) or (dividend < 0 and divisor > 0):
while divid1 >= divisor1:
n = 0 # 移位
# 找到最大的n,使得除数的2的n次方小于等于被除数
while divid1 >= (divisor1 << n):
n += 1
# 将被除数减去除数的2的n-1次方倍,并将结果累加到结果中
divid1 = divid1 - (divisor1 << (n-1))
result += 1 << (n-1)
# 返回负数结果
return -result
else: # 如果两个数同号,则最终结果为正数
while divid1 >= divisor1:
n = 0 # 移位
# 找到最大的n,使得除数的2的n次方小于等于被除数
while divid1 >= (divisor1 << n):
n += 1
# 将被除数减去除数的2的n-1次方倍,并将结果累加到结果中
divid1 = divid1 - (divisor1 << (n-1))
result += 1 << (n-1)
# 返回正数结果
return result