🤵Author:今日说“法”
🏆主攻领域:算法分析与设计
📰个人主页:今日说"法"的博客
📝系列专栏:NOWCODE系列
⚡️前言
一位大佬曾经说过:程序=数据结构+算法 ,数据结构相当于一套普遍适用的工具,算法相当于一套行之有效的解题方法和解题步骤。Dambisa Moyo 曾经说过:“种一颗树最好的时间是十年前,其次是现在。”所以十年前没有刷题的朋友,现在跟着博主一起刷题吧。
工具介绍:数组
定义
数组(Array)是一种线性表数据结构。它用一组连续的内存空间,来存储一组具有相同类型的数据。
结构
数组=一块连续的存储空间,我们假想数据下方有下标
优缺点
优点:查询/查找/检索其个下际上的元素时效事极高。可以说是查询效事最高的一个数据结构。
为什么检索效事高?
第一:每一个元素的内存地址在空间存储上是连续的。
第二:每一个元素类型相同,所以占用空间大小一样。
第三:知道第一个元素内存地址,知道每一个元素占用空间的大小,又知道下标,所以通过一个数学表达式就可以计算出某个下标上元素的内存地址。直接通过内存地址定位元素,所以数组的检索效事是最高的。
数组中存储100个元责,或者存结100万个元素,在元素查询/检索方面,效事是相同的。因为数组中元责查找的时候不会一个一个找,是通过数学表达式计算出来的。(算出一个内存地址,随接定位的。)
缺点:
第一:由于为了保证数组中每个元素的内存的加连续,所以在数组上随机制除或者增加元素的时候效事较纸,因为随机增别元责会涉及到后面元素统一向前或者向后位移的操作。
第二:数组不能存能大数据最,为什么?
因为很难在内存空间上找到一块特别大的连续的内存空间。
注意:对于数组中最后一个元素的增别,是没有效事影啊的。
CODE Exercise:
One:数组中的逆序对
难度:⭐⭐⭐ ⭐
时间限制:1秒
空间限制:256M
描述
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P mod 1000000007
数据范围: 对于 50% 的数据, size≤10^4
对于 100% 的数据, size≤10^5
数组中所有数字的值满足0≤val≤1000000
要求:空间复杂度 O(n),时间复杂度 O(nlogn)
输入描述:
题目保证输入的数组中没有的相同的数字
示例1
输入:[1,2,3,4,5,6,7,0]
返回值:7
示例2
输入:[1,2,3]
返回值:0
Submit(python)
# write code here
def merge_count(left,right):
l = 0
r = 0
data_tmp = []
count = 0
while l< len(left) and r <len(right):
if right[r]<left[l]:
data_tmp.append(right[r])
count = count + len(left)-l
r = r+1
else:
data_tmp.append(left[l])
l = l+1
while l<len(left):
data_tmp.append(left[l])
l = l+1
while r<len(right):
data_tmp.append(right[r])
r = r+1
return data_tmp, count
def merge(data):
n= len(data)
mid = n//2
if n <= 1:
return data, 0
if n>=2:
left, count_left = merge(data[0:mid])
right, count_right = merge(data[mid:])
orderlist, count_list = merge_count(left, right)
count = (count_left+count_right+count_list)
return orderlist,count
orderlist, count = merge(data)
return count %1000000007
Two:旋转数组的最小数字
难度:⭐⭐⭐
时间限制:1秒
空间限制:256M
描述
有一个长度为 n 的非降序数组,比如[1,2,3,4,5],将它进行旋转,即把一个数组最开始的若干个元素搬到数组的末尾,变成一个旋转数组,比如变成了[3,4,5,1,2],或者[4,5,1,2,3]这样的。请问,给定这样一个旋转数组,求数组中的最小值。
数据范围:1≤n≤10000,数组中任意元素的值: 0≤val≤10000
要求:空间复杂度:O(1) ,时间复杂度:O(logn)
示例1
输入:[3,4,5,1,2]
返回值:1
示例2
输入:[3,100,200,3]
返回值:3
Submit(python)
class Solution:
def minNumberInRotateArray(self, rotateArray):
# write code here
if not rotateArray:return None
left,right=0,len(rotateArray)-1
while left<right:
mid=(left+right)//2
if rotateArray[mid]>rotateArray[right]:
left=mid+1
elif rotateArray[mid]<rotateArray[right]:right=mid
else: right-=1
return rotateArray[left]
Three: 比较版本号
难度:⭐⭐⭐ ⭐
时间限制:1秒
空间限制:256M
描述
牛客项目发布项目版本时会有版本号,比如1.02.11,2.14.4等等
现在给你2个版本号version1和version2,请你比较他们的大小
版本号是由修订号组成,修订号与修订号之间由一个"."连接。1个修订号可能有多位数字组成,修订号可能包含前导0,且是合法的。例如,1.02.11,0.1,0.2都是合法的版本号
每个版本号至少包含1个修订号。
修订号从左到右编号,下标从0开始,最左边的修订号下标为0,下一个修订号下标为1,以此类推。
比较规则:
一. 比较版本号时,请按从左到右的顺序依次比较它们的修订号。比较修订号时,只需比较忽略任何前导零后的整数值。比如"0.1"和"0.01"的版本号是相等的
二. 如果版本号没有指定某个下标处的修订号,则该修订号视为0。例如,"1.1"的版本号小于"1.1.1"。因为"1.1"的版本号相当于"1.1.0",第3位修订号的下标为0,小于1
三. version1 > version2 返回1,如果 version1 < version2 返回-1,不然返回0.
数据范围:
1 <= version1.length, version2.length <= 1000
version1 和 version2 的修订号不会超过int的表达范围,即不超过 32 位整数 的范围
进阶: 空间复杂度 O(1) , 时间复杂度 O(n)
示例1
输入:"1.1","2.1"
返回值:-1
说明:version1 中下标为 0 的修订号是 "1",version2 中下标为 0 的修订号是 "2" 。1 < 2,所以 version1 < version2,返回-1
示例2
输入:"1.1","1.01"
返回值:0
说明:version2忽略前导0,为"1.1",和version相同,返回0
示例3
输入:"1.1","1.1.1"
返回值:-1
说明:"1.1"的版本号小于"1.1.1"。因为"1.1"的版本号相当于"1.1.0",第3位修订号的下标为0,小于1,所以version1 < version2,返回-1
示例4
输入:"2.0.1","2"
返回值:1
说明:version1的下标2>version2的下标2,返回1
示例5
输入:"0.226","0.36"
返回值:1
说明:226>36,version1的下标2>version2的下标2,返回1
Submit(python)
class Solution:
def compare(self , version1: str, version2: str) -> int:
# write code here
list1=version1.split('.')
list2=version2.split('.')
list1=[int(a) for a in list1 if int(a)!=0]
list2=[int(a) for a in list2 if int(a)!=0]
for i in range(min(len(list1),len(list2))):
if int(list1[i])>int(list2[i]) :
return 1
elif int(list1[i])<int(list2[i]) :
return -1
if len(list1)==len(list2):
return 0
if len(list1)<len(list2):
return -1;
return 1
🔥结语
❄️ 冰冻三尺非一日之寒❄️,只刷一两天刷法可成不了编程界的耶路撒冷,千里之行始于足下,所以还是得坚持刷题阿,每天记得要上机哟!!!