Python初学者笔记第九期 -- (列表相关操作及列表编程练习题)
第17节课 列表相关操作
无论是内置函数、对象函数,用起来确实很方便,但是作为初学者,你必须懂得它们背后的运行逻辑!
1 常规操作
(1)遍历
arr = [1,2,3,4]
# 以索引遍历:可以在遍历期间修改元素
for index in range(len(arr)):arr[index] = arr[index] ** 2print(arr[index])
print(arr)# 以元素遍历:只能获取元素,不能修改元素值(可变对象除外)
for element in arr:print(element)# 同时遍历角标和元素
for index, element in enumerate(arr):print(f"角标{index},元素{element}")# 反向遍历
for index in range(len(arr) - 1, -1, -1):print(arr[index])
(2)最值
def min_max(arr:list[int]) -> tuple:min_value = arr[0]max_value = arr[0]for i in range(1, len(arr)):if arr[i] > max_value:max_value = arr[i]if arr[i] < min_value:min_value = arr[i]return min_value, max_valuearr = [2,9,8,1,7,4,6,3,5]
min_val, max_val = min_max(arr)
print(min_val, max_val)
(3)存在性
arr = [2,9,8,1,7,4,6,3,5]
#O(n)
def is_exist(arr:list[int], key:int) -> bool:for element in arr:if element == key:return Truereturn Falseprint(is_exist(arr, 10))
print(is_exist(arr, 8))
(4)反转
arr = [1,2,3,4,5,6,7,8,9]
"""
1 2 3 4 5 6 7 8 9lr
"""
def list_reverse(arr:list[int]) -> None:l = 0r = len(arr) - 1while l < r:arr[l], arr[r] = arr[r], arr[l]l += 1r -= 1list_reverse(arr)
print(arr)
(5)乱序
import random
arr = [1,2,3,4,5,6,7,8,9]def list_shuffle(arr):for i in range(len(arr)):j = random.randint(0, len(arr) - 1)arr[i], arr[j] = arr[j], arr[i]list_shuffle(arr)
print(arr)
(6)二维列表
所谓的二维列表,其实本质上就是一个一维列表,只不过该一维列表中的每一个元素为其他的一维列表
def print_matrix(matrix):for i in range(len(matrix)):for j in range(len(matrix[i])):print(matrix[i][j], end = ' ')print()
# 直接填值创建二维列表
matrix = [[1,2,3], [4,5,6], [7,8,9]]
print(len(matrix))
print(len(matrix[1]))
print_matrix(matrix)
matrix = [[1,2,3,4],[1,2,3],[1,2],[1]
]
print_matrix(matrix)# 循环创建二维列表 指定默认值 0
rows = 3
cols = 5
matrix = []
for i in range(rows):row = [0] * colsmatrix.append(row)
matrix[2][2] = 6
print_matrix(matrix)# 列表推导式创建二维列表
matrix = [[0] * cols for _ in range(rows)]
matrix[2][2] = 6
print_matrix(matrix)matrix = [ [i + j for j in range(cols)] for i in range(rows)]
print_matrix(matrix)
2 查找操作
(1)二分查找
前提数据必须是有序的(升序、降序)
# 返回的是元素key在arr中的角标 如果不存在则返回-1
def binary_search(arr, key): #O(log n)left = 0right = len(arr) - 1mid = (left + right) // 2while arr[mid] != key:if arr[mid] < key:left = mid + 1elif key < arr[mid]:right = mid - 1if left > right:return -1# 重新更新mid的值mid = (left + right) // 2return mid# 顺序查找
def linear_search(arr, key):for index in range(len(arr)):if arr[index] == key:return indexreturn -1# arr = [1,2,3,4,5,6,7,8,9]
# key = 6
# print(binary_search(arr, key))
"""
n/2/2/2/2/..../2 = 1
n/2^x = 1
n = 2^x
x = logn
"""
arr = []
for i in range(70000000):arr.append(i)
key = 69999999
print("数据创建完毕...")
print(binary_search(arr, key))
print(linear_search(arr, key))
(2)插值查找
前提数据必须是有序的(升序、降序),它是二分查找的升级版本
# mid = (key - arr[left]) / (arr[right] - arr[left]) * (right - left) + left
# 当数据分布比较均匀的时候 大致满足等差序列的情况 性能要比二分查找要优秀
def interpalotion_search(arr, key):count = 0left = 0right = len(arr) - 1mid = 0# mid = int((key - arr[left]) / (arr[right] - arr[left]) * (right - left)) + left# while arr[mid] != key:# count += 1# if arr[mid] < key:# left = mid + 1# elif key < arr[mid]:# right = mid - 1# if left > right:# mid = -1# break# mid = int((key - arr[left]) / (arr[right] - arr[left]) * (right - left)) + leftwhile True:count += 1mid = int((key - arr[left]) / (arr[right] - arr[left]) * (right - left)) + left# key本身在范围外 没找到if mid < left or mid > right:mid = -1breakif arr[mid] < key:left = mid + 1elif key < arr[mid]:right = mid - 1else:break# 在范围内没找到if left > right:mid = -1breakprint(f"插值查找count={count}")return middef binary_search(arr, key): #O(log n)count = 0left = 0right = len(arr) - 1mid = (left + right) // 2while arr[mid] != key:count += 1if arr[mid] < key:left = mid + 1elif key < arr[mid]:right = mid - 1if left > right:mid = -1break# 重新更新mid的值mid = (left + right) // 2print(f"二分查找count={count}")return mid
# int((20 - 1)/(20-1) * (19 - 0)) + 0 = 19
# int((100 - 1)/(20 - 1) * (19 - 0))+ 0 = 99
# int((-100 - 1)/(20 - 1)*(19-0)) + 0 = - 101
arr= [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
key = -100
print(binary_search(arr, key))
print(interpalotion_search(arr, key))
3 排序操作
希尔排序、堆排序、快速排序、归并排序、计数排序、基数排序、桶排序
(1)选择排序
# 选择排序 O(n^2)
"""
从前往后 每一个元素都要跟其后面的其他元素作比较
如果出现左大右小 则进行交换
"""
def selection_sort(arr):for i in range(len(arr) - 1): # 少一轮for j in range(i + 1, len(arr)):if arr[i] > arr[j]:arr[i], arr[j] = arr[j], arr[i]
arr = [5,2,3,1,4]
selection_sort(arr)
print(arr)
(2)冒泡排序
# 冒泡 O(n^2)
"""
从前往后 元素之间两两进行比较
如果左大右小则交换
"""
def bubble_sort(arr):# 0 1 2 3for i in range(len(arr) - 1): #-1 少一轮for j in range(len(arr) - i - 1):if arr[j] > arr[j + 1]:arr[j], arr[j + 1] = arr[j + 1], arr[j]arr = [5,2,3,1,4]
bubble_sort(arr)
print(arr)
(3)插入排序
# 选择 O(n^2)
def insertion_sort(arr):# 从第2个元素开始遍历for i in range(1, len(arr)):j = iwhile j > 0 and arr[j - 1] > arr[j]:arr[j - 1], arr[j] = arr[j], arr[j - 1]j -= 1
arr = [5,2,3,1,4]
insertion_sort(arr)
print(arr)
根据循环的特性来去解决特定的问题,而不是学习循环本身,学算法思想!
循环之间的好坏其实也有区别,主要在于数据的分布情况
(1)大致升序
(2)大致降序
(3)趋于稳定(方差小,相等值比较多)
(4)完全随机
用time模块记录一下运行时间
第18节课 【列表编程练习题】
练习01 计算数字的出现次数
题目描述
读取1到100之间的整数,然后计算每个数出现的次数
输入输出描述
输入两行,第一行为整数的个数n,第二行为n个整数
输出多行,每行表示某数及其出现的次数,顺序按照数字从小到大
示例
输入:
9
2 5 6 5 4 3 23 43 2
输出:
2出现2次
3出现1次
4出现1次
5出现2次
6出现1次
23出现1次
43出现1次
# 思路1 借助Python自带功能去做
# def sovle(arr, n):
# arr.sort() #O(n*logn)
# for index in range(len(arr)):
# num = arr[index]
# # 对于第一个数字特殊处理
# # 与前一个数字不相等 第一次出现
# if index == 0 or num != arr[index - 1]:
# print(f"{num}出现{arr.count(num)}次")# 思路2 排序后 连续做比较
"""
num = 5
count = 2i1 1 1 2 2 3 3 3 4 5 5j
1=>3
2=>2
3=>3
4=>1
5=>1
"""
# def sovle(arr, n):
# #O(nlogn)
# arr.sort()
# i = 0
# # O(n)
# while i < n:
# num = arr[i]
# count = 1
# j = i + 1
# while j < n and arr[j] == arr[i]:
# count += 1
# j += 1
# print(f"{num}出现{count}次")
# print(f"j = {j}")
# i = j
# # 因为此题中需要用到 j = len(arr) 所以不能使用range()# 思路3 计数排序 非比较类排序 只针对整数 O(n + m)
# m 为最值之间的距离
# 牺牲空间 换 时间
def sovle(arr, n):# 找最大值和最小值min_value = min(arr) # O(n)max_value = max(arr) # O(n)# 创建计数数组counts = [0] * (max_value - min_value + 1)# 统计每个数字出现的次数for num in arr: # O(n)index = num - min_valuecounts[index] += 1# 遍历计数数组counts 打印每个数字出现的次数for index in range(len(counts)): #O(m)if counts[index] != 0:num = index + min_valueprint(f"{num}出现{counts[index]}")# 追加问题:如何排序好的数据打印出来?1 1 1 2 2 3 3 .......# 搞定输入问题
n = int(input())
arr = list(map(int, input().split(" ")))
sovle(arr, n)
练习02 最大公约数 II
题目描述
输入n个数字,求该n个数字的最大公约数
输入输出描述
输入n个数字
输出最大公约数
示例
输入:
9 12 18 21 15
输出:
3
def gcd(arr):min_value = min(arr)for i in range(min_value, 0, -1):for num in arr:if num % i != 0:breakelse:return i
arr = list(map(int, input().split(" ")))
print(gcd(arr))
练习03 按奇偶排序数组
题目描述
给你一个整数数组 nums,将 nums 中的的所有偶数元素移动到数组的前面,后跟所有奇数元素。
返回满足此条件的 任一数组 作为答案。
输入输出描述
输入数组长度n,接下来输入n个整数
输出排序后的数组
示例
输入:
4
3 1 2 4
输出:
2 4 3 1
解释:
[4,2,3,1]、[2,4,1,3] 和 [4,2,1,3] 也会被视作正确答案
# 思路1 创建新的数组 分开存奇偶 然后合并
"""
1 2 3 4 5 6 7 8
arr1 = 2 4 6 8
arr2 = 1 3 5 7
arr1 + arr2
"""
# 时间O(n) 空间S(n)
# def sovle(arr:list[int], n:int) -> list[int]:
# arr1 = []
# arr2 = []
# for num in arr:
# if num % 2 == 0:
# arr1.append(num)
# else:
# arr2.append(num)
# return arr1 + arr2# 思路2 双端队列 表头存偶 表尾存奇
# O(n) S(n)
# def sovle(arr:list[int], n:int) -> list[int]:
# deque = []
# for num in arr:
# if num % 2 == 0:
# deque.insert(0, num)
# else:
# deque.append(num)
# return deque
# 思路3 选择排序
# O(n^2) S(1)
# def sovle(arr:list[int], n:int) -> list[int]:
# for i in range(len(arr) - 1):
# for j in range(i + 1, len(arr)):
# if arr[i] % 2 == 1 and arr[j] % 2 == 0:
# arr[i], arr[j] = arr[j], arr[i]
# break
# return arr# 思路4 双指针
"""
是一种解题的思路 主要针对的是一维数据 数组/链表
同向指针 有两个角标都是从左到右的遍历
对向指针 有两个角标一个从头到尾遍历 另一个从尾到头遍历对数组进行分区间数组有序
快慢指针 同向的 一个走一步 另一走两步
滑动窗口 同向的 关于区间的问题
"""
# O(n) S(1)
# def sovle(arr:list[int], n:int) -> list[int]:
# left = 0
# right = len(arr) - 1
# while left < right:
# # 左偶右奇
# if arr[left] % 2 == 0 and arr[right] % 2 == 1:
# left += 1
# right -= 1
# # 左偶右偶
# elif arr[left] % 2 == 0 and arr[right] % 2 == 0:
# left += 1
# # 左奇右奇
# elif arr[left] % 2 == 1 and arr[right] % 2 == 1:
# right -= 1
# # 左奇右偶
# else:
# arr[left], arr[right] = arr[right], arr[left]
# return arr# *思路5 保证元素之间的相对顺序 *排序算法的稳定性*
"""
稳定性
现有一组无序数据 ....4(1).....4(2)....4(3).....
排序后 必须保证 ......4(1)4(2)4(3).....
"""
def sovle(arr:list[int], n:int) -> list[int]:# 冒泡 O(n^2)# for i in range(len(arr) - 1):# for j in range(len(arr) - 1 - i):# if arr[j] % 2 == 1 and arr[j + 1] % 2 == 0:# arr[j], arr[j + 1] = arr[j + 1], arr[j]# 插入 O(n^2)for i in range(1, len(arr)):if arr[i] % 2 == 1:continuej = iwhile j > 0 and arr[j - 1] % 2 == 1:arr[j], arr[j - 1] = arr[j - 1], arr[j]j -= 1return arrn = int(input())
arr = list(map(int, input().split()))
print(sovle(arr, n))
练习04 合并两个有序数组
题目描述
给定两个有序递增的数组A和数组B,将其进行合并成一个新的数组C,且保持有序递增,并输出数组C
输入输出描述
第一行输入数组A的长度n,第二行输入n个元素,第三行输入数组B的长度m,第四行输入m个元素
输出数组C的n+m个元素
示例
输入:
5
1 5 16 61 111
4
2 4 5 6
输出:
1 2 4 5 5 6 16 61 111
# 思路1 合并后排序 O(nlogn) S(n)
# def solve(arr1, arr2):
# arr3 = []
# arr3.extend(arr1)
# arr3.extend(arr2)
# arr3.sort()
# return arr3# 思路2 按照从小到大 交叉合并 O(n) S(n)
# def solve(arr1, arr2):
# length1 = len(arr1)
# length2 = len(arr2)
# arr3 = [0] * (length1 + length2)
# p1 = 0
# p2 = 0
# p3 = 0
# while p3 < len(arr3):
# if p1 < length1 and p2 >= length2:
# arr3[p3] = arr1[p1]
# p1 += 1
# elif p2 < length2 and p1 >= length1:
# arr3[p3] = arr2[p2]
# p2 += 1
# elif arr1[p1] <= arr2[p2]:
# arr3[p3] = arr1[p1]
# p1 += 1
# else:
# arr3[p3] = arr2[p2]
# p2 += 1
# p3 += 1
# return arr3# 思路3 同一个数组有两个子区间各自有序 问合并后的结果(原地排序)?
# 归并排序的核心思路
# L-M-R含义是对数组中某一个区间进行合并
def solve(arr, L, M, R):temp = []for i in range(L, R + 1):temp.append(arr[i])p1 = 0p2 = M + 1 - Lp3 = Lwhile p3 <= R:if p1 <= M - L and p2 > R - L:arr[p3] = temp[p1]p1 += 1elif p1 > M - L and p2 <= R - L:arr[p3] = temp[p2]p2 += 1elif temp[p1] <= temp[p2]:arr[p3] = temp[p1]p1 += 1else:arr[p3] = temp[p2]p2 += 1p3 += 1
"""
1 2 3 4 2 3 6 8"""# n = int(input())
# arr1 = list(map(int, input().split(" ")))
# m = int(input())
# arr2 = list(map(int, input().split(" ")))
# arr3 = solve(arr1, arr2)
# print(arr3)# 思路3
arr = [1,2,3,4,2,3,4,5,6,7,8,9,2,3,6,8]
solve(arr, 8, 11, 15)
print(arr)
练习05 数组划分
题目描述
给定一个数组A,将第一个元素 A 0 A_0 A0作为枢纽,并把数组划分成三个区间,第一个区间所有元素 < A 0 <A_0 <A0,第二个区间所有元素 = = A 0 ==A_0 ==A0,第三个区间所有元素 > A 0 >A_0 >A0
例如数组[5,2,9,3,6,8],划分后的结果为[3,2,5,9,6,8],第一个区间[3,2],第二个区间[5],第三个区间[9,6,8]
结果不唯一,只要保证划分后三个区间的元素特性即可,[2,3,5,9,8,6]、[3,2,5,6,8,9]都可作为上述划分的结果
输入输出描述
第一行输入数组的长度n,第二行输入n个元素
输出划分后的结果
示例
输入:
10
5 1 9 2 5 7 4 5 3 6
输出:
1 2 4 3 5 5 5 9 7 6
# 快速排序的核心思路 O(n) S(1)
def solve(arr,L, R):if L >= R:returnlt = Lgt = R + 1v = arr[L]i = L + 1while i < gt:# 小于vif arr[i] < v:arr[i], arr[lt + 1] = arr[lt + 1], arr[i]lt += 1i += 1# 等于velif arr[i] == v:i += 1# 大于velse:gt -= 1arr[gt], arr[i] = arr[i], arr[gt]arr[L], arr[lt] = arr[lt], arr[L]print(arr)# 同样操作左边区间solve(arr, L, lt - 1)# 同样操作右边区间solve(arr, gt, R)arr = [4,1,6,3,6,8,2,4,6,2,3,6,4,2,4,9,7,5,3,5,3,2,4,5,4,5,4]
solve(arr,0, len(arr) - 1)
print(arr)
练习06 长度最小的子数组
题目描述
给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其总和大于等于 target 的长度最小的 连续子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
输入输出描述
输入数组长度n和目标值target,接下来输入n个元素
输出最小子数组长度
示例
输入:
6 7
2 3 1 2 4 3
输出:
2
解释:
子数组 [4,3] 是该条件下的长度最小的子数组
# 思路1 暴力破解 枚举 O(n^2)
"""
优化思路:
1.过滤没有必要的计算
2.避免重复的计算
"""
"""
def sovle(arr, target):min_length = len(arr) + 1for i in range(len(arr)):cur_sum = 0for j in range(i, len(arr)):sub_arr = arr[i:j + 1]cur_sum += arr[j]if cur_sum >= target:min_length = min(len(sub_arr), min_length)print(sub_arr, cur_sum)breakif min_length != len(arr) + 1:return min_lengthelse:return 0
"""
# 思路2 O(n) S(1)
def sovle(arr, target):left = 0right = 0cur_sum = arr[left]min_length = len(arr) + 1while True:if cur_sum < target:right += 1if right >= len(arr):breakcur_sum += arr[right]else:cur_length = right - left + 1min_length = min(cur_length, min_length)cur_sum -= arr[left]left += 1if left > right:breakif min_length == len(arr) + 1:return 0else:return min_length
arr = [2,3,1,2,4,3]
# i
# j
target = 7
ret = sovle(arr, target)
print(ret)
练习07 寻找两个正序数组中的中位数
题目描述
给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。
算法的时间复杂度应该为 O(log (m+n)) 。
输入输出描述
输入m和n,然后分别输入m个元素和n个元素
输出中位数
示例1
输入:
2 1
1 3
2
输出:
2.0
解释:
合并数组 = [1,2,3] ,中位数2
示例2
输入:
2 2
1 2
3 4
输出:
2.5
def solve(nums1, nums2):length1 = len(nums1)length2 = len(nums2)if length1 > length2:return solve(nums2, nums1)if length1 == 0:if length2 % 2 == 1:return nums2[length2 // 2]else:return (nums2[length2 // 2] + nums[length2 // 2 - 1]) / 2result = 0 # 中位数的结果L = 0R = length1curA = 0curB = 0total = length1 + length2while L <= R:curA = (L + R) // 2curB = (total + 1) // 2 - curAL1 = -99999999 if curA == 0 else nums1[curA - 1]R1 = 999999999 if curA == length1 else nums1[curA]L2 = -99999999 if curB == 0 else nums2[curB - 1]R2 = 999999999 if curB == length2 else nums2[curB]if L1 > R2:R = curA - 1elif L2 > R1:L = curA + 1else:if total % 2 == 0:result = (max(L1, L2) + min(R1, R2)) / 2else:result = max(L1, L2)breakreturn resultnums1 = [2,4,6,8]
nums2 = [1,3,5,7,9]
print(solve(nums1, nums2))
练习08 豆机器
题目描述
豆机器,也称为梅花或高尔顿盒子,它是一个统计实验的设备,它是由一个三角形直立板和均匀分布的钉子构成,如下图所示:

小球从板子的开口处落下,每次小球碰到钉子,它就是50%的可能掉到左边或者右边,最终小球就堆积在板子底部的槽内
编程程序模拟豆机器,提示用户输入小球的个数以及机器的槽数,打印每个球的路径模拟它的下落,然后打印每个槽子中小球的个数
输入输出描述
输入两个数据,分别表示小球个数和槽子的个数
输出每个小球经过的路径,和最终每个槽子里小球的个数(因为牵扯随机数,程序结果不唯一,示例仅用于表明题意)
示例
输入:
5 8
输出:
LRLRLRR
RRLLLRR
LLRLLRR
RRLLLLL
LRLRRLR
0 0 1 1 3 0 0 0
import random
# balls球的个数 sluts槽子的个数
def solve(balls, sluts):# 定义槽子这个数组arr = [0] * sluts# 模拟每个球下落的路径for _ in range(balls):# 每个球下落几次?sluts - 1次path = ""# 模拟下落的过程 拼接路径index = 0 # 这个球下落的在槽子中的角标for _ in range(sluts - 1):r = random.randint(0, 1)if r == 0:path += "L"else:path += "R"# 计算小球下落的槽子角标index += 1print(path)arr[index] += 1 # 累加槽子中小球的个数return arrballs, sluts = map(int, input().split(" "))
arr = solve(balls, sluts)
# 画图表示一下 柱状图
# pip list 查看python第三方库
# pip install XXX 安装XXX第三方库
import matplotlib.pyplot as plt
plt.bar(list(range(sluts)), arr)
plt.show()
练习09 四个连续的相同数字
题目描述
给定一个二维数组,判断其中是否有四个连续的相同数字,不管这四个数字是在水平方向、垂直方向还是斜线方向
输入输出描述
输入矩阵的行列n和m
输出YES表示存在,NO不存在
示例
输入:
5 5
5 6 2 1 6
6 5 6 6 1
1 3 6 1 4
3 6 3 3 4
0 6 2 3 2
输出:
YES
def is_lianxu(matrix, row, col):length_row = len(matrix)length_col = len(matrix[row])# 向右if col <= length_col - 4:for c in range(col + 1, col + 4):if matrix[row][col] != matrix[row][c]:breakelse:print(matrix[row][col])return True# 向下if row <= length_row - 4:for r in range(row + 1, row + 4):if matrix[row][col] != matrix[r][col]:breakelse:print(matrix[row][col])return True# 向右下if col <= length_col - 4 and row <= length_row - 4:r = row + 1c = col + 1while r < row + 4 and c < col + 4:if matrix[row][col] != matrix[r][c]:breakr += 1c += 1else:print(matrix[row][col])return True# 向左下if row <= length_row - 4 and col >= 3:r = row + 1c = col - 1while r < row + 4 and c > col - 4:if matrix[row][col] != matrix[r][c]:breakr += 1c -= 1else:print(matrix[row][col])return Truereturn Falsedef sovle(matrix):for row in range(len(matrix)):for col in range(len(matrix[row])):if is_lianxu(matrix, row, col):return Truereturn Falsematrix = [[5,6,2,1,6],[3,5,6,6,1],[1,3,6,1,4],[3,6,3,3,4],[0,6,2,3,2]
]
print(sovle(matrix))
练习10 找出最近距离的一对点
输入一组点的坐标,寻找哪两个点的距离最近。先输入点的个数 n,然后在输入 n 行点坐标。
示例1
输入:
8
-1 3
-1 -1
1 1
2 0.5
2 -1
3 3
4 2
4 -0.5
输出:
(1,1)与(2,0.5)最近
"""
8
-1 3
-1 -1
1 1
2 0.5
2 -1
3 3
4 2
4 -0.5
"""
n = int(input())
points = []
for _ in range(n):point = list(map(float, input().split(" ")))points.append(point)distance = -1
p1 = None
p2 = None# 开始计算两两之间点的距离
for i in range(len(points) - 1):for j in range(i + 1, len(points)):cur_p1 = points[i] # [-1, 3]cur_p2 = points[j] # [-1, -1]cur_dist = ((cur_p1[0] - cur_p2[0]) ** 2 + (cur_p1[1] - cur_p2[1]) ** 2) ** 0.5if distance == -1:distance = cur_distelif cur_dist < distance:distance = cur_distp1 = cur_p1p2 = cur_p2
print(p1)
print(p2)
print(distance)
练习11 探索二维矩阵 I
题目描述
给你一个满足下述两条属性的 m x n 整数矩阵:
- 每行中的整数从左到右按非递减顺序排列。
- 每行的第一个整数大于前一行的最后一个整数。
给你一个整数 target ,如果 target 在矩阵中,返回 true ;否则,返回 false 。
输入输出描述
输入矩阵的行row和列col,和目标值target
接下来输入row行,每行col个元素
输出是否存在
示例
输入:
3 4 3
1 3 5 7
10 11 16 20
23 30 34 60
输出:
true
# 思路1 先卡区间 再对行进行二分查找
# def binary_search(arr, target):
# low = 0
# high = len(arr) - 1
# mid = (low + high) // 2
# while arr[mid] != target:
# if arr[mid] < target:
# low = mid + 1
# else:
# high = mid - 1
# if low > high:
# mid = -1
# break
# mid = (low + high) // 2
# return mid# def solve(matrix, target):
# row = len(matrix) # 行数
# col = len(matrix[0]) # 列数
# # 先看是否存在与整个范围内
# if target < matrix[0][0] or target > matrix[row - 1][col - 1]:
# return -1, -1
# for i in range(row):
# line = matrix[i]
# if line[0] <= target <= line[col - 1]:
# return i, binary_search(line, target)
# matrix = [
# [1,3,5,7],
# [10,11,16,20],
# [23,30,34,60]
# ]
# target = 0
# x, y = solve(matrix, target)
# if x == -1 or y == -1:
# print("不存在")
# else:
# print(x, y)# 思路2 将全体进行二分查找
def sovle(matrix, target):row = len(matrix) # 行数col = len(matrix[0]) # 列数low = 0high = row * col - 1while low <= high:mid = (high + low) // 2cur = matrix[mid // col][mid % col]if cur == target:return Trueelif cur < target:low = mid + 1else:high = mid - 1return Falsematrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]
]
target = 12
print(sovle(matrix, target))
练习12 拉丁方阵
拉丁方阵是指一个含有n个不同拉丁字母的 n × n 的方阵,每个字母在方阵的每一行和每一列都只出现一次。编写一个程序,程序提示用户输入方阵的大小 n,然后输入一个方阵,检测是否为拉丁方阵。方阵的字母是从A开始的n个字母。
示例1
输入:
4
A B C D
B A D C
C D B A
D C A B
输出:
是拉丁方阵
示例2
输入:
3
A B C
C A B
A C B
输出:
不是拉丁方阵
示例3
输入:
3
A F H
输出:
因为 n = 3,所以字母只能是A、B、C
"""
4
A B C D
B A D C
C D B A
D C A B
"""
def is_lading(matrix, aim):# 取每一行for i in range(len(matrix)):line = matrix[i].copy()line.sort()if line != aim:return False# 取每一列for j in range(len(matrix[0])):line = []for i in range(len(matrix)):line.append(matrix[i][j])line.sort()if line != aim:return Falsereturn Truen = int(input())
matrix = []
for _ in range(n):# "A B C D" => ["A","B","C","D"]matrix.append(input().split(" "))
# 确定查找目标 n = 4 -> ["A","B","C","D"]
aim = [ chr(i + 65) for i in range(n)]
print(is_lading(matrix, aim))
练习13 五子棋游戏
五子棋是一种双人对弈的棋类游戏,双方分别使用黑白两色棋子,在棋盘上交替落子。游戏目标为在棋盘的横向、纵向或斜向任一方向上,使自己的五个同色棋子连成一线。通常先手执黑子,后手执白子,轮流在棋盘的交叉点上放置棋子,先达成五连珠的玩家获胜。
棋盘由纵横各 15 条线交叉组成,形成 225 个交叉点。棋子分为黑、白两色,黑子 113 枚,白子 112 枚。
提示用户每次下棋的坐标即可。
def create_board():board = []for _ in range(15):line = []for _ in range(15):line.append("+")board.append(line)return board
def print_board(board):for i in range(15):for j in range(15):print(board[i][j], end=" ")print()# 具体下棋的逻辑
def down_chess(board, chess, player):x, y = map(int,input(f">>>请{player}下棋:").split(" "))# 下棋之前需要判断一下此处是否已经有棋子了if board[x - 1][y - 1] == "+":board[x - 1][y - 1] = chessprint_board(board)else:print(">>>此处已有棋子,请重新下棋!")down_chess(board, chess, player)def is_game_over(board):for row in range(15):for col in range(15):if board[row][col] != "+":# 向右if col < 11:for c in range(col + 1, col + 5):if board[row][col] != board[row][c]:breakelse:return True# 向下if row < 11:for r in range(row + 1, row + 5):if board[row][col] != board[r][col]:breakelse:return True# 右下if row < 11 and col < 11:r = row + 1c = col + 1while r < row + 5 and c < col + 5:if board[row][col] != board[r][c]:breakr += 1c += 1else:return True# 左下if row < 11 and col > 3:r = row + 1c = col - 1while r < row + 5 and c > col - 5:if board[row][col] != board[r][c]:breakr += 1c -= 1else:return Truereturn Falsedef start_game(board):count = 0while not is_game_over(board):# 将棋子下到棋盘上if count % 2 == 0:down_chess(board, "●", "黑方")else:down_chess(board, "○", "白方")count += 1print(">>>游戏结束!")
def main():# 创建棋盘board = create_board()# 打印棋盘print_board(board)# 开始游戏逻辑start_game(board)main()"""
给棋盘加序号 在print_board加
和棋怎么办 数棋子数
最终谁赢 count
悔棋(限制悔棋一步) 栈
"""
相关文章:
Python初学者笔记第九期 -- (列表相关操作及列表编程练习题)
第17节课 列表相关操作 无论是内置函数、对象函数,用起来确实很方便,但是作为初学者,你必须懂得它们背后的运行逻辑! 1 常规操作 (1)遍历 arr [1,2,3,4] # 以索引遍历:可以在遍历期间修改元素 for ind…...
设备指纹破解企业面临的隐私与安全双重危机
在数字经济高速发展的今天,黑灰产攻击如影随形,个人隐私泄露、金融欺诈、电商刷单等风险事件频发。芯盾时代 “觅迹” 设备指纹全新升级,以跨渠道识别能力打破行业壁垒,为金融、电商、游戏等多场景构筑安全屏障。 黑灰产肆虐隐私…...
多功能气体检测报警系统,精准监测,守护安全
在化学品生产、石油化工、矿山、消防、环保、实验室等领域,有毒有害气体泄漏风险严重威胁工作人员和环境安全。化工企业生产中易产生大量可燃有毒气体,泄漏达一定浓度易引发爆炸、中毒等重大事故;矿井下瓦斯、一氧化碳等有害气体的浓度实时监…...
【HarmonyOS 5】鸿蒙中常见的标题栏布局方案
【HarmonyOS 5】鸿蒙中常见的标题栏布局方案 一、问题背景: 鸿蒙中常见的标题栏:矩形区域,左边是返回按钮,右边是问号帮助按钮,中间是标题文字。 那有几种布局方式,分别怎么布局呢?常见的思维…...
登顶中国:基于 Trae AI与 EdgeOne MCP 的全国各省最高峰攀登攻略博客构建实践
一、背景与目标 随着户外运动和登山活动的日益流行,越来越多的人希望挑战自然,体验登顶的乐趣。中国幅员辽阔,34个省级行政区(包括23个省、5个自治区、4个直辖市和2个特别行政区)拥有众多壮丽的山峰,其…...
iOS蓝牙技术实现及优化
以下是针对2025年iOS蓝牙技术实现的核心技术要点的深度解析,结合当前iOS 18(推测版本)的最新特性与开发实践,分模块结构化呈现: 一、硬件与协议层适配 BLE 5.3 支持 iOS 18默认支持蓝牙5.3协议,需注意&…...
STC单片机--仿真调试
目录 一、仿真介绍二、仿真步骤 一、仿真介绍 通常单片机的仿真有ST-Link、JTAG等,连接好线路之后,在keil的debug选项设置好就可以仿真了。但是,STC需要在STC-ISP软件上的仿真界面进行配置,然后才能在keil里正常仿真 二、仿真步骤…...
SecureCRT SFTP命令详解与实战
在日常的开发工作中,安全地进行文件传输是一个常见的需求。无论是部署应用到远程服务器,还是从生产环境下载日志文件分析问题,一个可靠的工具可以大大提高工作效率。今天,我们就来详细介绍如何使用SecureCRT内置的SFTP功能&#x…...
Unity Gizmos
简介 Gizmos 是Unity编辑器中的一种可视化调试工具,用于在场景视图(Scene View)中绘制辅助图形、图标或文本,帮助开发者直观理解游戏对象的位置、范围、逻辑关系等信息 核心功能 1. 辅助可视化调试 在场景视图中显示碰撞体、触…...
EEG设备的「减法哲学」:Mentalab Explore如何用8通道重构高质量脑电信号?
在脑电图(EEG)研究领域,选择适配的工具是推动研究进展的重要步骤。Mentalab Explore 以其便捷性和高效性,成为该领域的一项创新性解决方案。研究者仅用较少的 EEG 通道即可完成实验,并且能够确保数据的高质量。其搭载的…...
PDF文档压缩攻略
前言:早上花了一点时间网上搜索了一下压缩pdf文档大小的方法,发现大部分是利用第三方在线网页,上传文件付费压缩,同时缺乏文件保密性。 经实践,利用浏览器或者wps(不付费)即可轻松处理。 一、…...
vllm命令行启动方式并发性能实测
设备V100双卡,测试模型qwen2.5-7b,并发度为100。 表现如下: 单卡959.48token/s 双卡 使用 --pipeline-parallel-size 2 939.78token/s双卡 使用 --tensor-parallel-size 21084.82token/s双卡,两张卡分别跑一个接口,形成两个接口…...
医疗AI存在 9 类系统性漏洞
医疗AI存在9类系统性漏洞 理解1. 从整体目的入手2. 关键术语:什么是“红队测试”(Red Teaming)?3. 红队测试的对象:LLM(大模型)4. 红队测试的切入点:为什么要让“临床专家”来做?5. 什么叫做“脆…...
怎么有效管理项目路径(避免使用绝对路径)
怎么有效管理项目路径(避免使用绝对路径) import os 使用 os.path 方法会自动处理不同操作系统的路径分隔符(如 \ 和 /) 1.**current_dir os.path.dirname(os.path.abspath(\__file__)) ** __file__ 获取当前脚本的文件路径&…...
MySQL的行级锁锁的到底是什么?
大家好,我是锋哥。今天分享关于【MySQL的行级锁锁的到底是什么?】面试题。希望对大家有帮助; MySQL的行级锁锁的到底是什么? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 MySQL的行级锁是数据库管理系统(DBMS)的一…...
多账号管理、反追踪与自动化测试:我的浏览器实战笔记
作为一名在自动化测试和数据采集方面“踩坑”无数的开发者,我想聊聊自己在浏览器工具选择上的一些经验,也许能帮到同样在“账号风控”“浏览器指纹”“隐私追踪”这些问题上挣扎的朋友们。 一、从最初的Chrome开始:万能但不够隐蔽 起初做Se…...
如何应对客户在验收后提出新需求?
应对客户在验收后提出新需求的方法包括:明确新需求的范围与影响、与客户积极沟通、进行影响评估、合理协商费用与时间调整。其中,明确新需求的范围与影响最为关键。明确新需求的范围意味着迅速界定新需求的边界,分析它对现有项目进度、成本和…...
Android Studio根目录下创建多个可运行的模块
右键选中根目录,选择New -> Module 接着选中Phone & Tablet, 填写项目名和包名 选择一个模板,选择Next 然后可以看到app对应一开始创建的app模块,刚创建的customcomponent对应的,这样就可以在一个根目录下有多个可以安装运…...
【Linux】Linux环境基础开发工具
前言 本篇博客我们来了解Linux环境下一些基础开发工具 💓 个人主页:zkf& ⏩ 文章专栏:Linux 若有问题 评论区见📝 🎉欢迎大家点赞👍收藏⭐文章 目录 1.Linux 软件包管理器 yum 2.Linux开发工具 2.1…...
五子棋html
<!DOCTYPE html> <html lang"zh-CN"> <head> <meta charset"UTF-8" /> <meta name"viewport" content"widthdevice-width, initial-scale1" /> <title>五子棋游戏</title> <style>bo…...
分布式-基于数据库排他锁
原理: 除了可以通过增删操作数据表中的记录以外,其实还可以借助数据库中自带的锁来实现分布式的锁。 我们还用刚刚创建的那张数据库表。可以通过数据库的排他锁来实现分布式锁。 基于MySql的InnoDB引 擎,可以使用以下方法来实现加锁操作&…...
docker host模式问题
为什么乌班图得docker 我装什么都必须要host 而-p映射不管用 在 Ubuntu 上使用 Docker 时,如果你发现只有 --network host 模式能正常工作,而端口映射(-p)不管用,可能有以下几种原因: 1. Docker 网络模式…...
分布式-Redis分布式锁
Redis实现分布式锁优点 (1)Redis有很高的性能; (2)Redis命令对此支持较好,实现起来比较方便 实现思路 (1)获取锁的时候,使用setnx加锁,并使用expire命令为锁…...
【Python爬虫电商数据采集+数据分析】采集电商平台数据信息,并做可视化演示
前言 随着电商平台的兴起,越来越多的人开始在网上购物。而对于电商平台来说,商品信息、价格、评论等数据是非常重要的。因此,抓取电商平台的商品信息、价格、评论等数据成为了一项非常有价值的工作。本文将介绍如何使用Python编写爬虫程序&a…...
大数据应用开发和项目实战-电商双11美妆数据分析2
数据可视化 使用seaborn库绘制复杂图表,展示各品牌和品类的销售情况。 绘制嵌套柱形图,分别按主类别和子类别进行对比。 通过饼图展示男士专用产品的销售偏好,发现男士主要关注清洁和补水类产品。 用seaborn包给出每个店铺各个大类以及各个…...
GSENSE2020BSI sCMOS科学级相机主要参数及应用场景
GSENSE2020BSI sCMOS科学级相机是一款面向宽光谱成像需求的高性能科学成像设备,结合了背照式(Back-Side Illuminated, BSI)CMOS技术与先进信号处理算法,适用于天文观测、生物医学成像、工业检测等领域。以下是其核心特点及技术细节…...
基于深度学习的交通标志识别系统
基于深度学习的交通标志识别系统 项目简介 本项目实现了一个基于深度学习的交通标志识别系统,使用卷积神经网络(CNN)对交通标志图像进行分类识别。系统包含数据预处理、模型训练与评估、结果可视化和用户交互界面等模块。 数据集 项目使用德国交通标志识别基准数…...
Golang的linux运行环境的安装与配置
很多新手在学go时,linux下的配置环境一头雾水,总结下,可供参考! --------------------------------------Golang的运行环境的安装与配置-------------------------------------- 将压缩包放在/home/tools/下 解压 tar -zxvf g…...
时间序列数据集增强构造方案(时空网络建模)
时间序列数据集增强构造方案(时空网络建模) 时间序列数据集TimeSeriesDataset 时间序列数据集增强EnhancedTimeSeriesDataset 一、方案背景与动机 1.1 背景分析 传统时间序列预测方法(如ARIMA、Prophet等)以及很多深度学习方法…...
实验六 基于Python的数字图像压缩算法
一、实验目的 掌握图像压缩的必要性; 掌握常见的图像压缩标准; 掌握常见的图像压缩方法分类; 掌握常见的图像压缩方法原理与实现(包括哈夫曼编码、算术编码、行程编码方法等); 了解我国音视…...
Vue 3 中的 nextTick 使用详解与实战案例
Vue 3 中的 nextTick 使用详解与实战案例 在 Vue 3 的日常开发中,我们经常需要在数据变化后等待 DOM 更新完成再执行某些操作。此时,nextTick 就成了一个不可或缺的工具。本文将介绍 nextTick 的基本用法,并通过三个实战案例,展示…...
Docker + Watchtower 实现容器自动更新:高效运维的终极方案
文章目录 前言一、Watchtower 简介二、Watchtower 安装与基本使用1. 快速安装 Watchtower2. 监控特定容器 三、Watchtower 高级配置1. 设置检查间隔2. 配置更新策略3. 清理旧镜像4. 通知设置 四、生产环境最佳实践1. 使用标签控制更新2. 更新前执行健康检查3. 结合CI/CD流水线 …...
OpenCV 中用于背景分割(背景建模)的一个类cv::bgsegm::BackgroundSubtractorGSOC
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 cv::bgsegm::BackgroundSubtractorGSOC 是 OpenCV 中用于背景分割(背景建模)的一个类,它是基于 GMMÿ…...
AI恶魔之眼使用说明书
AI恶魔之眼使用说明书 产品简介 1.1 产品介绍 AI恶魔之眼是一款具备动态视觉效果与仿生眼睛模拟功能的智能显示产品,可实现以下特性: 真实人眼模拟:支持虹膜样式变换、眨眼动画、瞳孔缩放等动态特效,仿真度高自定义内容上传&am…...
PBR材质-Unity/Blender/UE
目录 前言: 一、Unity: 二、Blender: 三、UE: 四、全家福: 五、后记: 前言: PBR流程作为表达物理效果的经典方式,很值得一学。纹理贴图使用的是上一期的Textures | cgbookcas…...
C++复习
线程库(类) 在C11之前,涉及到多线程问题,都是和平台相关的,比如Windows和Linux下各有自己的接口,这使得代码的可移植性比较差。C11中最重要的特性就是对线程进行了支持,使得C在并行编程时不需要依赖第三方…...
如何使用docker配置ros-noetic环境并使用rviz,gazebo
参考链接:【Ubuntu】Docker中配置ROS并可视化Rviz及Gazebo_docker ros-CSDN博客 前言: 其实这个东西是相当必要的,因为我们有时候需要在一台电脑上跑好几个项目,每个项目都有不同的依赖,这些依赖冲突搞得人头皮发麻&…...
计算机网络中相比于RIP,路由器动态路由协议OSPF有什么优势?
好的!以下是关于路由信息协议(RIP,Routing Information Protocol)的技术原理详解,以及其与OSPF(Open Shortest Path First)的对比分析。内容分为技术原理、对比优势和不足两部分。 一、RIP技术原理深度解析 1. 基本概念 协议类型:RIP属于距离向量路由协议(Distance-V…...
相似命令对比
awk 命令用法表格 场景命令示例说明示例输入文件内容 (input.txt)输出结果1. 基础字段提取awk -F: {print $1} /etc/passwd按分隔符提取第1列(如用户名)。root:x:0:0:root:/root:/bin/bashroot2. 多字段组合输出awk -F: {print $1, $3, $7} /etc/passwd…...
Vuerouter 的底层实现原理
文章目录 前言🧩 Vue Router 底层实现核心原理🧠 执行流程图(简化版)🔍 核心模块源码原理(简要)① 路由注册与匹配(createRouterMatcher)② 历史模式管理器(c…...
按拼音首字母进行排序组成新的数组(vue)
数据按首字母相同的组成新的数组,使用拼音(Pinyin)转换 比如想要的效果: 下载 npm install pinyin代码: import pinyin from "pinyin"; let studentAllList [{onLine: true,points: undefined…...
在IPv6头部中,Next Header字段
在IPv6头部中,Next Header字段 在IPv6头部中,Next Header字段是一个8位的字段,它的作用是指示下一个头部扩展的类型或者最终的传输层协议类型。这个字段的值决定了数据包中紧随IPv6头部之后的头部扩展的类型,或者是直接指向传输层…...
vue项目部署后部分子页面刷新后403
经过我的仔细分析;终于找到了是刷新后路径后面自动拼接了 / ;如 66.66.66.66/aPage 刷新后变成了 66.66.66.66/aPage/ 导致403 方法一: 修改路由为hash模式 // router/index.jsimport { createRouter, createWebHistory, createWebHashHist…...
C# NX二次开发:曲线和点位相关UFUN函数详解
大家好,今天要介绍查询曲线上点位和返回沿着曲线偏移一定距离的UFUN函数。 (1)UF_MODL_ask_curve_points:这个函数的定义为按照给定条件查询曲线上的点位。 Defined in: uf_modl_curves.h Overview Returns an array of 3D …...
服务器数据恢复—硬盘坏道导致EqualLogic存储不可用的数据恢复
服务器存储数据恢复环境&故障: 一台EqualLogic某型号存储中有一组由16块SAS硬盘组建的RAID5阵列。上层采用VMFS文件系统,存放虚拟机文件,上层一共分了4个卷。 磁盘故障导致存储不可用,且设备已经过保。 服务器存储数据恢复过程…...
【2019 CWE/SANS 25 大编程错误清单】12越界写入
案例1: void tonly_aw21036_led_drv_pwm_init(tonly_gpio_pin_t gpio_pin, uint8_t pwm) {uint8_t pin gpio_pin - AW21036_GPIO_PIN_START;if (pin < AW21036_LED_MAX_CHANNEL){aw21036_ctx.pwm[pin] pwm; /* 有效通道号: 0-35 */}else{TONLY_LED_LOG_E(&qu…...
redis bitmap数据类型调研
一、bitmap是什么? redis原文: Bitmaps are not an actual data type, but a set of bit-oriented operations defined on the String type . This means that bitmaps can be used with string commands, and most importantly with SET and GET. 翻…...
[Windows] Ghost Downloader v3.5.9 开源多线程下载工具
[Windows] Ghost Downloader 链接:https://pan.xunlei.com/s/VOPejV3veb6v-im-wVmMkXkhA1?pwdpzwk# Ghost Downloader 是一款专为Windows平台设计的多线程下载工具,完全由Python语言开发。它以其高效的多线程下载技术和断点续传功能而著称,…...
互联网大厂Java求职面试:AI集成与云原生架构设计
互联网大厂Java求职面试:AI集成与云原生架构设计 面试场景:技术总监与程序员郑薪苦的对话 技术总监:郑薪苦,我们今天来聊聊你在AI集成场景中的经验。你有没有尝试过将Spring AI与大模型结合? 郑薪苦:有啊…...
gitignore的相关用法
gitignore .gitignore 是 git 用于管理需要忽略追踪的文件。.gitignore 一般用于远程仓库多人协作的场景,最常见的情况是,使用 MacOS 系统的程序员要在 .gitignore 中添加 .DS_Store 防止将其推送至仓库中。或在开发代码时,将调试文件忽略&a…...