一维数组刷题
1.题目名称:加一
66.加一
class Solution:
def plusOne(self, digits):
tail = len(digits) - 1
carry = 0
while tail >= 0:
if digits[tail] < 9:
digits[tail] += 1
return digits
else:
digits[tail] = 0
carry = 1
tail -= 1
if carry == 1:
digits.insert(0, 1)
return digits
def plusOne2(self, digits):
'''
1.从后往前遍历 digits, 进位 carry 默认为0
2.如果 该元素值 <9 , 加1 返回
3.否则(=9),该元素值赋值为 0, carry = 1
4.依次遍历,最后如果 carry == 1 , 则开头增加一位 1.
'''
carry = 0
n = len(digits)
for i in range(n-1, -1, -1):
if digits[i] < 9:
digits[i] += 1
return digits
else:
digits[i], carry = 0, 1
if carry == 1:
return [1] + digits
my_list = [1, 9, 9]
solution = Solution()
res = solution.plusOne(my_list)
print(res)
res = solution.plusOne2([9, 9, 9])
print(res)
2.轮转数组
189.轮转数组
class Solution:
def rotate(self, nums: list, k: int):
"""
Do not return anything, modify nums in-place instead.
给你一个数组,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。
eg:
输入:nums = [-1,-100,3,99], k = 2
输出:[3,99,-1,-100]
解释:
向右轮转 1 步: [99,-1,-100,3]
向右轮转 2 步: [3,99,-1,-100]
思路:
直接调用 list 中的 方法,执行时间有点长,时间复杂度:O(n), 空间复杂度:O(n)
"""
for i in range(k):
nums.insert(0, nums.pop())
pass
def rotate2(self, nums: list, k: int):
'''
思路:使用新数组, 以空间换时间
1.假如 i 表示 数组的下标, k 表示移动的长度,n是数组的长度,则 移动之后i对应的新的下标为 (i+k)%n
'''
n = len(nums)
new_list = []
for i, num in enumerate(nums):
new_index = (i+k) % n
new_list.insert(new_index, num)
for i in range(n):
nums[i] = new_list[i]
pass
def rotate3(self, nums: list, k: int):
''' 环形替换(重点掌握):
思路:不定义新数组,在原数组的基础上实现
1.开始 i = 0, 定义 temp = nums[0], new_index = (i + k) mod n
2.重复步骤1,遍历 1圈回到 nums[0], 之后 i = 1,继续重复 步骤1
3.循环 gcd(n, k) 次(证明较麻烦,先记住,或者使用count记录每次遍历的元素个数,count == n时 结束)
时间复杂度:
空间复杂度:O(1)
'''
def gcd(m, n):
'''求最大公约数'''
if m < n:
m, n = n, m
while(n != 0):
r = m%n
m = n
n = r
return m
pass
n = len(nums)
k = k % n
cnt = gcd(n, k)
for i in range(cnt):
current = i
temp = nums[current]
while True:
new_index = (current + k) % n
temp, nums[new_index] = nums[new_index], temp
current = new_index
if current == i:
break
return nums
def rotate4(self, nums, k):
"""环形替换:循环次数使用 cnt 记录 元素个数,cnt == n 时结束循环"""
n = len(nums)
current = start = 0
cnt = 0
while cnt < n:
temp = nums[current]
while True:
new_index = (current + k) % n
temp, nums[new_index] = nums[new_index], temp
current = new_index
cnt += 1
if current == start:
current += 1
start += 1
break
return nums
def rotate5(self, nums, k):
'''数组反转:
eg:
nums = [1, 2, 3, 4, 5, 6, 7]; k = 3
1.全部反转 [7, 6, 5, 4, 3, 2, 1]
2.reverse(nums, 0, k-1) : [5, 6, 7, 4, 3, 2, 1]
3.reverse(nums, k, len(nums)): [5, 6, 7, 1, 2, 3, 4]
'''
def reverse(nums:list, start:int, end:int):
while start < end:
nums[start], nums[end] = nums[end], nums[start]
start, end = start+1, end-1
pass
n = len(nums)
k %= n
reverse(nums, 0, n-1)
reverse(nums, 0, k-1)
reverse(nums, k, n-1)
pass
s = Solution()
nums = [1,2,3,4,5,6,7]
s.rotate5(nums, 3)
print(nums)
3.寻找数组的中心下标
寻找数组的中心下标
class Solution:
"""
1.从头开始遍历 nums[]
2.index=0, 左边为0; index=len(nums)-1 右边为0
3.判断 index左边的所有元素之和 是否等于 右边的所有元素之和
4.第一次满足条件的则返回 下标,遍历完没有找到,则返回 -1
eg:
输入:nums = [1, 7, 3, 6, 5, 6]
输出:3
解释:
中心下标是 3 。
左侧数之和 sum = nums[0] + nums[1] + nums[2] = 1 + 7 + 3 = 11 ,
右侧数之和 sum = nums[4] + nums[5] = 5 + 6 = 11 ,二者相等
这种2层循环,时间复杂度是 O(n^2) 效率太低
"""
def pivotIndex(self, nums: list):
n = len(nums)
lsum , rsum = 0, 0
for i in range(0, n):
for j in range(0, i):
lsum += nums[j]
for j in range(i+1, n):
rsum += nums[j]
if lsum == rsum:
return i
lsum, rsum = 0, 0
return -1
'''
改进:
1.记数组的总和为 total
2.求index 元素 左边的和 lsum
3.则 index 右边的元素和 : total - lsum - nums[index]
4.若 total - lsum - nums[index] = lsum 即返回下标index . 即 total = 2*lsum + nums[index]
'''
def pivotIndex2(self, nums:list):
n = len(nums)
total = sum(nums)
lsum = 0
for i in range(0, n):
lsum += nums[i-1] if i > 0 else 0
if total == 2*lsum + nums[i]:
return i
return -1
nums = [1, 7, 3, 6, 5, 6]
s = Solution()
res = s.pivotIndex2(nums)
print(res)
4.最大连续1的个数
最大连续1的个数
class Solution:
'''
给定一个二进制数组 nums , 计算其中最大连续 1 的个数。
eg:
输入:nums = [1,1,0,1,1,1]
输出:3
解释:开头的两位和最后的三位都是连续 1 ,所以最大连续 1 的个数是 3.
思路:
'''
def findMaxConsecutiveOnes(self, nums: list):
maxCnt = cnt = 0
for i in nums:
if i == 1:
cnt += 1
else:
maxCnt = max(maxCnt, cnt)
cnt = 0
maxCnt = max(maxCnt, cnt)
return maxCnt
nums = [0, 0, 0, 0]
s = Solution()
res = s.findMaxConsecutiveOnes(nums)
print(res)
附录
原文链接