#list--列表,可以存储各种元素,利用append向尾部添加一个元素,利用+号,可以添加多个,如re+=a[0:]
#append添加元素后,不需要赋值,如a=[]1,2,3],a.append(1),print(a),结果即为[1,2,3,1]
# 用remove去掉列表中的元素,也不需要赋值
#利用set设置一个集合,元素不可重复,ll=set().利用add添加元素,
#range(6)--[0,1,2,3,4,5],range(1,6)----[1,2,3,4,5]
#ord把对应的字符串转化为十进制,
#chr返回当前整数的ASCII字符,chr(97),输出a
#num=[1,2,3,4,5] num[::-1]=[5,4,3,2,1]
#res=[0 for _ in range(n)]初始化数组长度
#1-----给定数字区间的质数
#1、查找是否是质数,判断是否小于2,则返回false,大于2则判断在2和该数的平方根之间,是否能被该数整除,整除则返回false,剩余返回true
#2、给定一个空数组,判断在该范围内,是否是质数,如果是质数,则拼接到数组中
# import math
# def is_prime(num):
# if num<2:
# return False
# for i in range(2,int(math.sqrt(num))+1):
# print(i)
# if num%i==0:
# return False
#
# return True
# def find(start,end):
# arry=[]
# for i in range(start,end+1):
# if is_prime(i):
# arry.append(i)
# return arry
# sum=find(2,4)
# print(sum)
# print(int(math.sqrt(4))+1)
#2----双指针
# #重排链表
# # L0 → L1 → … → Ln-1 → Ln
# # 请将其重新排列后变为:
# # L0 → Ln → L1 → Ln-1 → L2 → Ln-2 → …
#思路:通过快慢指针找到中间节点,然后将后面节点反转链表,然后开始拼接
# class ListNode:
# def __init__(self,data):
# self.data=data
# self.next=None
# #找到中间节点,并排序
# def Nnew_order(LList):
# if LList is None or LList.next is None:
# return LList
# quick=LList
# slow=LList
# while quick.next and quick:
# slow=slow.next
# quick = quick.next.next
# resever=slow.next
# slow.next=None
# prev=reserver_list(resever)
# p1, p2 = LList, prev
#
# while p2:
# tmp1, tmp2, p2 = p1.next, p2.next, p2.next
# # 将p2插入p1之后,并更新p1和p2的位置指针
# p1.next = prev
# prev.next = tmp1
#
# p1, prev = tmp1, tmp2
#
# return LList
# # 反转链表
# def reserver_list(LList):
# pre=None
# cur=LList
# while cur:
# nnext=cur.next
# cur.next=pre
# pre=cur
# cur=nnext
# return pre
# if __name__=='__main__':
# head =ListNode(1)
# head1 =ListNode(2)
# head2 = ListNode(3)
# head3 = ListNode(4)
# head4 = ListNode(5)
# head.next=head1
# head1.next=head2
# head2.next=head3
# head3.next=head4
# headll=Nnew_order(head)
# # print(headll.data)
# # headll=reserver_list(head)
# headnn=headll
# while headnn:
# print(headnn.data,end=" ")
# headnn=headnn.next
#4-------数字字符串转为ip地址
# def restore_ip_addresses(s):
# result = []
# backtrack(s, [], result)
# return result
#
# def backtrack(s, path, result):
# # IP地址由四个部分组成,如果已经找到了四个部分并且s也为空,则说明找到了一个合法的IP地址
# if len(path) == 4 and not s:
# result.append(".".join(path))
# return
#
# # IP地址的每一部分最多有三位数,循环尝试不同长度的子串,并继续递归查找下一部分
# for i in range(1, 4):
# if i <= len(s):
# num = int(s[:i])
#
# # 排除掉以0开头但长度大于1的数字
# if str(num) == s[:i] and num <= 255:
# print(i, s[i:],str(num),s[:i], path + [s[:i]], result)
# backtrack(s[i:], path + [s[:i]], result)
#
# if __name__=='__main__':
# s = "25525511110"
# print(restore_ip_addresses(s))
# #5------二叉树遍历
#做法:先创建一个树节点,判断树为空,则返回空,否则创建一个空的列表,先添加头,再添加左节点,右节点
#中序遍历,先遍历左节点,然后头节点,然后右节点
#后序遍历,先遍历左节点,然后右节点,然后头节点
# #前序遍历
# class TreeNode:
# def __init__(self,val=0,left=None,right=None):
# self.val=val
# self.left=left
# self.right=right
# def presort(root):
# if root is None:
# return []
# result=[]
# result.append(root.val)
# result+=presort(root.left)
#
# result+=presort(root.right)
# return result
# if __name__=='__main__':
# root=TreeNode(2)
# root.left = TreeNode(4)
# root.right=TreeNode(5)
# root.left.right=TreeNode(6)
# root.left.left=TreeNode(7)
# root.right.right = TreeNode(1)
# root.right.left = TreeNode(3)
# print(presort(root))
#5-----链表尾插法
#若头节点是空,就将值赋值给头节点,若头节点不为空,则判断下个节点是否为空,为空则赋值给该节点,不为空则继续next
# class ListNode:
# def __init__(self,data):
# self.data=data
# self.next=None
# class End_insert:
# def __init__(self):
# self.head=None
# def append(self,data):
# newNode=ListNode(data)
# if self.head is None:
# self.head=newNode
# else:
# curr=self.head
# while curr.next:
# curr=curr.next
# curr.next=newNode
# def display(self):
# if self.head is None:
# return "空链表"
# else:
# curr=self.head
# while curr:
# print(curr.data,end='')
# curr=curr.next
# if __name__=="__main__":
# Elist=End_insert()
# Elist.append(1)
# Elist.append(2)
# Elist.append(3)
# Elist.display()
# #6-----反转链表
# #先定义节点,当链表为空或者只有一个节点,返回该节点
# #否则,定义一个节点pre为空,一个节点curr指向head,当head不为空时,保存head->next节点为nnextt,
# #反转节点,cur->next指向pre,更新pre为cur,cur为nnext
# class ListNode:
# def __init__(self, data):
# self.data = data
# self.next = None
# def reverseLinkedList(head):
# # 如果链表为空或只有一个节点,直接返回头节点
# if head is None or head.next is None:
# return head
# prev = None # 前一个节点
# curr = head # 当前节点
# while curr is not None:
# next_node = curr.next # 下一个节点
# curr.next = prev # 反转指针方向
# prev = curr # 更新前一个节点为当前节点
# curr = next_node # 更新当前节点为下一个节点
# return prev # 返回新的头节点
# if __name__=='__main__':
# head=ListNode(1)
# head1=ListNode(3)
# head2=ListNode(4)
# head3 = ListNode(5)
# head.next=head1
# head1.next=head2
# head2.next=head3
# reversed_head=reverseLinkedList(head)
# print(reversed_head.data)
# current_node = reversed_head
# while current_node is not None:
# print(current_node.data, end=" ")
# current_node = current_node.next
# #7----- 归并排序
# #merge的功能是将前后相邻的两个有序表归并为一个有序表的算法。
# #merge_sort利用递归进行排序
# def merge(left, right):
# ll, rr = 0, 0
# result = []
# while ll < len(left) and rr < len(right):
# if left[ll] < right[rr]:
# print(type(result))
# result.append(left[ll])
# ll += 1
# else:
# result.append(right[rr])
# rr += 1
# print("ces@@@" + str(ll), result)
# result+=left[ll:]
# print("ces++++"+str(ll),result)
# result+=right[rr:]
# print("ces----"+str(rr),result)
# return result
# def merge_sort(alist):
# if len(alist) <= 1:
# return alist
# num = len(alist) // 2 # 从中间划分两个子序列
# left = merge_sort(alist[:num]) # 对左侧子序列进行递归排序
# right = merge_sort(alist[num:]) # 对右侧子序列进行递归排序
# return merge(left, right) #归并
#
# if __name__=='__main__':
# arlis=[1,2,5,6,9,2,3,12,34,5,6,2]
# print(merge_sort(arlis))
# #8------最大不重复子串-----滑动窗口:当重复则去除元素,移动窗口
#set设置集合,用add添加元素
# #初始化一个集合(元素无序且不重复的集合),遍历,不重复的时候,将值添加到列表中,重复的时候,移除前面的列表,重新开始循环
# def maxLength(arra):
# arr_queue=set()
# start=0
# max_length=1
# for i in range(len(arra)):
# while arra[i] in arr_queue:
# arr_queue.remove(arra[start])
# start+=1
# arr_queue.add(arra[i])
# max_length=max(max_length,i-start+1)
# print(arr_queue,max_length)
# return max_length
# if __name__=='__main__':
# res=maxLength([1,2,4,5,6,7,8363,3,3,2,4])
# print(res)
#10-----装饰器
# class Logger:
# def __init__(self,args):
# self.args1=args
# def __call__(self,func):
# def wrapper(*args,**kwargs):
# print("开始测试",self.args1)
# func(*args,**kwargs)
# print("测试结束")
# return wrapper
# @Logger('---567---')
# def make():
# print('测试一123')
# if __name__=='__main__':
# make()
#11-----冒泡排序---排序n-1趟
#思想:比较相邻元素大小,逆序则调换位置,排序n-1趟
#时间复杂度O(n).O(n^2)
#空间复杂度:O(1)
# class Camper():
# def maopao(self, a):
# for i in range(1,len(a)):
# for j in range(0,len(a)-1):
# if a[j]>a[j+1]:
# b=a[j]
# a[j]=a[j+1]
# a[j+1]=b
# print(a)
# if __name__=='__main__':
# C=Camper()
# an=[1,2,5,12,6,7]
# C.maopao(an)
#插入排序 O(N),O(N2),o(1)--100个数字最坏需要N(N-1)/2次排序
#思路,是默认前n-1个元素数据是有序的,将n个元素插入到前面有序的序列中,使得前N个元素有序
#记录有序序列的最后一个元素end=i,并将下一个元素赋值给temp=nums[end+1]
# def insertSort(nums):
# if len(nums)<2:
# return nums
# for i in range(len(nums)-1):
# #记录有序序列的最后一个元素的下标
# end=i
# #待插入的元素
# tmp=nums[end+1]
# while end>=0:
# #比插入的数大就向后移
# if tmp<nums[end]:
# nums[end+1]=nums[end]
# end-=1
#比插入的数小,跳出循环
# else:
# break
# nums[end+1]=tmp #注意前面已经end-1了,此时需要+1
# return nums
# if __name__=='__main__':
# an = [1, 2, 5, 12, 6, 7]
# insertSort(an)
# print(insertSort(an))
#希尔排序 O(N) 平均0(N^1.3)
#按照gap取中间值作为增量,进行插入排序,取中间数,最后一次在进行插入排序,
#如: 1 4 3 2 7 5
#gap=3,则 1 和2比较,4和7比较,2和5比较,前面小于后面则退出循环,大于则交换
#gap=1,则进行一波插入排序
# def hashSort(nums):
# if len(nums)<2:
# return nums
# gap=len(nums)
# while gap>1:
# #每次循环折半操作
# gap = gap // 2
# print(gap)
# for i in range(len(nums)-gap):#注意gap
#
# end=i
# tmp=nums[end+gap]
# while end>=0:
# if tmp<nums[end]:
# nums[end+gap]=nums[end]
# end-=1
# else:
# break
# nums[end+gap]=tmp
# return nums
#
# if __name__=='__main__':
# an = [1, 2, 5, 12, 6, 7]
# hashSort(an)
# print(hashSort(an))
#选择排序
#思路:排序n-1遍,每遍找出最小值,然后放到列表的其实位置
#O(N^2),O(N^2)
# def selectSort(nums):
#
# n=len(nums)
# if n<2:
# return nums
# for i in range(n-1):
# mindex=i
# for j in range(i+1,n):
# if nums[j]<nums[mindex]:
# mindex=j
#
# if mindex!=i:
# tmp=nums[i]
# nums[i]=nums[mindex]
# nums[mindex]=tmp
# return nums
# if __name__=="__main__":
# print(selectSort([1, 2, 5, 12, 6, 7]))
#快排,快慢指针
# def QuickSort(nums,begin,end):
# if begin>=end:
# return nums
# left=begin
# right=end
# key = nums[begin] #注意key要提前赋值,不要弄下标,要赋值
# while left<right:
# while nums[right]>=key and left<right:
# right-=1
# nums[left]=nums[right]
# while nums[left]<key and left<right:
# left+=1
# nums[right] = nums[left]
# nums[left]=key
# QuickSort(nums,begin,left-1)
# QuickSort(nums,left+1,end)
#
# return nums
# if __name__=='__main__':
# nums=[1, 3, 2,2, 4, 7]
#
# print(QuickSort(nums,0,len(nums)-1))
# #9------快速排序---判断长度是否大于等于2,key值为数组取一半长度
#O(N*log2N)
#设置两个空的数组left,right,key取长度的一半取整数,然后去除key,当值大于key时,拼接到左边,否则,拼接到右边
# ,递归left,right,最后拼接left+key+right
# class Quicksort:
# def quick(self,array):
# if len(array)>=2:
# key=array[len(array)//2]
# left=[]
# right=[]
# array.remove(key)
# for val in array:
# if val<key:
# left.append(val)
# else:
# right.append(val)
# print(left,key,right)
# return self.quick(left)+[key]+self.quick(right)
# else:
# return array
# if __name__=='__main__':
# QS=Quicksort()
# res=QS.quick([1,4,56,7,8,9,0,343])
# print(res)
#12------单链表有无环
#快慢指针
#先创建一个节点,设置p1,p2都指向头部节点,p2先走两步,p1走一步,当p1==p2时,则有环
# class isRoll():
# def __init__(self,X):
# self.X=X
# self.next=None
# def is_roll(llist):
#
# p1=p2=llist
# while p1 and p2.next:
# p1=p1.next
# p2=p2.next.next
# if p1==p2:
# return True
# return False
# if __name__=="__main__":
# head=isRoll(1)
# head1=isRoll(3)
# head2=isRoll(4)
# head3=isRoll(5)
# head.next=head1
# head1.next=head2
# head2.next=head3
# head3.next=head2
# print(is_roll(head))
#13-----实现删除链表的倒数N个节点---快慢节点指向虚拟节点,快节点先移动N个位置,然后移动快慢节点,快节点为空时,慢节点为N节点的前置节点
#1、定义一个虚拟节点,快慢节点,快慢节点指向虚拟节点;
#2、将快节点移动N个位置
#3、判断快节点.next和快节点存在,移动慢节点和快节点---当快节点为空时,此时慢节点为N节点的前置节点
#4、将慢节点的next指向慢节点的next.next,即-删除该节点
# class LListNode:
# def __init__(self,data):
# self.data=data
# self.next=None
# def delete_node(Lnode,num):
# dummy=LListNode(0)
# dummy.next=Lnode
# fast=dummy
# slow=dummy
# for i in range(num):
# fast=fast.next
# while fast and fast.next:
# slow=slow.next
# fast=fast.next
# slow.next=slow.next.next
# return dummy.next
# if __name__=='__main__':
# head=LListNode(2)
# head.next=LListNode(3)
# head.next.next=LListNode(5)
# head.next.next.next=LListNode(9)
# head.next.next.next.next = LListNode(10)
# head.next.next.next.next.next = LListNode(12)
# res=delete_node(head,4)
# while res:
# print(res.data,end='')
# res=res.next
#一个整数数组nums和两个整数indexDiff和valueDiff,
#14-----比较版本号
#忽略前导零,如1.01,1.001,01和001都表示1,返回0;如1.0,1.0.0,1.0无下标为2视为0,则返回0
# def Compare_ver(version1:str,version2:str):
# n,m=len(version1),len(version1)
# i,j=0,0
# while i < n or j<m:
# x = 0
# while i<n and version1[i]!='.':
# x=x*10+ord(version1[i])-ord('0')
# i+=1
# i+=1
# y=0
# while j<m and version2[j]!='.':
# y=y*10+ord(version2[j])-ord('0')
# j+=1
# j+=1
# print(x,y)
# if x!=y:
# if x>y:
# return 1
# else:
# return -1
# return 0
#
# res=Compare_ver('14.56','14.567')
# print(res)
#15----输入无序数组:
#输入:numbers = [2,15,11,16,7,8,1], target = 9
#输出:[1,2]
# def get_order(numbers:list,target:int):
# res=[]
# while len(numbers)>=2:
# for i in range(len(numbers)):
# for j in range(i+1,len(numbers)):
# print(i,j)
# if numbers[i]+numbers[j]==target:
# res+=[i,j]
# return res
# # return '不存在'
# return "不存在两位数"
# res=get_order([2,15,11,16,7,8,1],9)
# print(res)
#16----输入有序数组:通过二分查找方式,查找
#输入:numbers = [2,7,11,15], target = 9
#输出:[1,2]
# def get_nub(number:list,target:int):
# n=len(number)
# for i in range(n):
# low=i
# high=n
# while low<high:
# mid=(high+low)//2
# if number[mid]+number[i]==target:
# return [i+1,mid+1]
# elif number[mid]+number[i]>target:
# high=mid-1
# else:
# low=mid+1
# return [-1,-1]
#
# res=get_nub([2,7,11,15],13)
# print(res)
#17------EXCEL表列名称:输入数字27,输出列数AA,
# A -> 1
# B -> 2
# C -> 3
# ...
# Z -> 26
# AA -> 27
# AB -> 28
# def coverTotitle(columnNumber:int):
# vo=[]
# while columnNumber>0:
# a0=(columnNumber)%26
# vo.append(chr(a0+ord('A')))
# columnNumber=(columnNumber)//26
# return "".join(vo[::-1])
# res=coverTotitle(2147483647)
# print(res)
#合并两个有序序列---拼接后直接快排
# def merge( nums1: [int], m: int, nums2: [int], n: int) -> None:
# """
# Do not return anything, modify nums1 in-place instead.
# """
# nums1[m:] = nums2[:n]
# print(nums1)
# res=sorts(nums1)
# print(res)
# def sorts(num):
# if len(num)>=2:
#
# left=[]
# right=[]
# key = num[len(num) // 2]
# num.remove(key)
# for val in num:
# if val<key:
# left.append(val)
# else:
# right.append(val)
# # print(sorts(left)+[key]+sorts(right))
# return sorts(left)+[key]+sorts(right)
# else:
# return num
# print(sorts([1,3,6,2,12,3,4]))
# merge([1,2,3,5],4,[2,3,4],3)
#移除元素--双指针,返回新的长度,和包含超出元素的新数组
#不用管多出来的元素,所以直接判断是否等于给出的值,不等于则后面赋值给前面
# def removeElement(nums:[],val:int):
# left=0
# # right=0
# for right in range(len(nums)):
# if nums[right]!=val:
# nums[left]=nums[right]
# left+=1
# return left,nums
# res=removeElement([0,1,2,2,3,0,4,2],2)
# print(res)
#删除有序数组中的重复项
#双指针前指针p,后指针q.当num[p]!=num[q],将q赋值给P+1,同时移动p,q往后走一步,否则,q走一步
# def removeDuplicates(nums: [int]):
# left=0
# n=len(nums)
# for right in range(n):
# if nums[right] != nums[left]:
# nums[left + 1] = nums[right]
# right += 1
# left += 1
# else:
# right += 1
# return left+1,nums
# print(removeDuplicates([0,0,1,1,1,2,2,3,3,4]))
#请你 原地 删除重复出现的元素,使得出现次数超过两次的元素只出现两次 ,返回删除后数组的新长度。
#输入:nums = [1,1,1,2,2,3]
# 输出:5, nums = [1,1,2,2,3]
# def removeDuplicates(nums):
# left=2
# right=2
# if len(nums)<=2:
# return 0
# while(right<len(nums)):
# if nums[left-2]!=nums[right]:
# nums[left]=nums[right]
# left+=1
# right+=1 #注意此处
# return left
#
# print(removeDuplicates([1,1,1,2,2,3]))
# #给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。
# #输入:nums = [3,2,3]
# # 输出:3
# def majorityElement(nums):
# nums.sort()
# return nums[len(nums)//2]
# print(majorityElement([3,2,3]))
#轮转数组--取余(i+k)%(len(nums)),同时注意新的数组需要初始化长度
#输入: nums = [1,2,3,4,5,6,7], k = 3
#输出: [5,6,7,1,2,3,4]
# def rotate( nums:[int], k: int) -> None:
# """
# Do not return anything, modify nums in-place instead.
# """
# n = len(nums)
# res=[0 for _ in range(n)]
#
# for i in range(n):
# res[(i + k) % n] = nums[i]
# for i in range(n):
# nums[i] = res[i]
# return nums
# print(rotate([1,2,3,4,5,6],3))
#卖卖股票的时机
#输入:[7,1,5,3,6,4]
#输出:5
# def maxProfit( prices: [int]) -> int:
# maxlength = 0
# for i in range(len(prices) - 1):
# for j in range(i + 1, len(prices)):
# res = prices[j] - prices[i]
# maxlength = max(maxlength, res)
# return maxlength
# print(maxProfit([7,1,5,3,6,4]))
#公共前缀
#判断该数组是否为空,为空则返回空,否则,初始化prefix=数组[0],从1开始循环,
# 查找公共前缀:得出两个数组(prefix,数组[i])的最小长度,比较是否小于最小长度,当两个数组相等时,+1,
#将公共前缀赋值给prefix
# def clf(str1,str2):
# index=0
# minstr=min(len(str1),len(str2))
# while index<minstr and str1[index]==str2[index]:
# index+=1
# return str1[:index]
# def longestCommonPrefix(strs:[str]):
# if not strs:
# return ""
# prefix=strs[0]
# for i in range(1,len(strs)):
# prefix=clf(prefix,strs[i])
# if not prefix:
# break
# return prefix
# strs = ["flower","flow","flight"]
# print(longestCommonPrefix(strs))
#删除特定子串
#如'aaaaacbbacc',删除ac,输出aaaabbc
# def delstr(ss):
# if ss=='':
# return ""
# i=0
# while i<len(ss):
# if ss[i]=='c' and ss[i-1]=='a' and i>0:
# if i==1:
# ss=ss[2:]
# elif i==len(ss)-1:
# ss=ss[:i-1]
# break
# else:
# ss=ss[:i-1]+ss[i+1:]
# i+=1
# else:
# i+=1
# return ss
# strd = 'aaaaacbbacc'
# print(delstr(strd))
#斐波那契
#F(0)=0,F(1)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 2,n ∈ N*)
# def f(n):
# if n<2:
# return n
# return f(n-1)+f(n-2)
# if __name__=='__main__':
# n=100
# for i in range(n):
# print(f(i),end=' ')
# #列表中出现次数最多的元素
#设置字典
# def maxCount(nums):
# counts={}
# for val in nums:
# if val in counts:
# counts[val]+=1
# else:
# counts[val]=1
# maxcoun=0
# elements={}
# for val,counts in counts.items():
# if counts>maxcoun:
# maxcoun=counts
# elements=val
#
# return elements
# if __name__=='__main__':
# nums=[1,2,3,4,2,1,1,1,6]
# print(maxCount(nums))
#先排序再找出重复数字
# def findnum(nums):
# n=len(nums)
# if n<2:
# return nums
# for i in range(n-1):
# end=i
# tmp=nums[end+1]
# while end>=0:
# if tmp<nums[end]:
# nums[end+1]=nums[end]
# end-=1
# else:
# break
# nums[end+1]=tmp
# res=[]
# for i in range(n-1):
# if nums[i]==nums[i+1]:
# res.append(nums[i])
# else:
# continue
# return res,nums
# if __name__=='__main__':
# print(findnum([1,3,2,3,1,5,6]))
#四个数字组成多少个互不相同且无重复数字的三位数
# def norepeat(nums):
# res=[]
# count=0
# for i in range(1,5):
# for j in range(1,5):
# for m in range(1,5):
# if i!=j and i!=m and j!=m:#注意判断三个都不等
# res.append(i*100+j*10+m)
# count+=1
# return res,count
# if __name__=='__main__':
# print(norepeat([1,2,3,4]))
#字符串切分的反向操作
# def reverse_split(ss,de):
# result=[]
# cour=''
# for val in ss:
# if val==de:
# result.append(cour)
# cour=''
# else:
# cour+=val
# result.append(cour)
# return result
# if __name__=='__main__':
# ss='hello,word,ni'
# de=','
# print(reverse_split(ss,de))
#
算法练习——列表/链表/二叉树/滑动窗口---knowledge
于 2024-02-01 14:10:28 首次发布