1.寻找数组中出现次数超过一半的数(剑指offer39题)
思路1:建立一个和输入数组一样大小的数组,用来记录每个数字出现的数,
最后判断出现次数大于等于1/2len的取出来。(时间复杂度高)

l = [int(n) for n in input().split()]
#创建记录数组
b = [None]*len(l)
for i in range(len(l)):
    b[i]=0
max=0
#对应位置的数字出现一次,记录数组加一
for i in range(len(l)):
    for j in range(len(l)):
        if l[i]==l[j]:
            b[i]+=1
for i in range(len(l)):
    if (b[i])>=(1/2)*len(l):
        max=l[i]
print(max)

思路2:摩尔投票法,一对一消耗,留下来的数字为众数。(技巧)

n=len(nums)
term = nums[0]
count=0
for i in range(n):
    if nums[i]==term:
        count+=1
    else:
        count-=1
        if count==0:
            term = nums[i+1]
return term

2.一组无序的自然数集合,由0,1,2… …,n的数字和一个的数字X(X>=0 && X<=n)组成,请从集合中找出这个重复数字X。
思路:创建一个相同的数组记录每个数字出现的次数,判断出现次数大于1即为所求。

l = [int(n) for n in input().split()]
#创建记录数组
b = [None]*len(l)
for i in range(len(l)):
    b[i]=0
index=0
#出现几,在位置为几的下标加1
for i in range(len(l)):
    b[l[i]]+=1
for i in range(len(l)):
    if b[i]>1:
        out=i
print(out)

第二种解法:见12
3.数组中寻找第K大的数值
给定一个无序的整型数组A[n],数组大小大于等于3,允许有值相同的元素;请设计算法找到该数组排序后第三大的元素值并输出。
例:输入[6,5,4,4,1,2] 输出4

ins = input()
l = list(map(int, ins[1:-1].split(',')))
l.sort()
print(l[len(l)-3])

4.连续子数组最大和
输入一个整形数组(可能有正数和负数),求数组中连续子数组(最少有一个元素)的最大和。要求时间复杂度为O(n)。
思路:遍历所有以i (1≤i≤n)为后边界的最大子段和B[i]得出最优解:
B[i] = MAX(B[i-1]+A[i], A[i])

n = int(input(""))
A=[None]*n
for i in range(n):
    A[i]=int(input(""))
B=[None]*n
for i in range(n):
    B[i]=0
#第一个位置的数分别赋给 记录数组B,max。
B[0]=A[0]
max=A[0]
for i in range(1, n):
    #如果之前的结果大于0,则用B[i-1]+当前位置数字  否则直接赋值当前位置数字
    if B[i-1]>=0:
        B[i]=B[i-1]+A[i]
    else:
        B[i]=A[i]
    if B[i]>max:
        max=B[i]
print(max)

5.零子数组
长度为N的数组A中子数组和最接近0的子数组。
思路:step1:两种可能 要么子数组从0到j,要么子数组从i到j。
step2:从0到j的情况,直接比较前j项累加和,取绝对值最小的。
从i到j的情况,先对前j项和累加 然后排序,计算相邻之间的差值取最小。(相邻说明数字接近,越接近差值越有可能为0)

lis = [int(n) for n in input().split()]
sum = [None]*len(lis)
sum[0]=lis[0]
for i in range(1,len(lis)):
    sum[i]=sum[i-1]+lis[i]
abssum=[abs(n) for n in sum]
min1=min(abssum)
sum.sort()
for i in range(len(sum)-1):
    term=sum[i+1]-sum[i]
    if term<min1:
        min1=term
print(term)

6.连续子数组最大积
给你一个整数数组 nums ,请你找出数组中乘积最大的连续子数组(该子数组中至少包含一个数字)
思路:以0分割数组;遇到0则初始化乘积为1.
如果数组内负数为偶数个,则最大值为数组内所有值乘积。
如果数组内负数为奇数个,则最大值可能为从前往后乘到最后一个负数之前,也可能为从后往前乘到第一负数之后。

n=len(nums)
term = 1
max=nums[0]
for i in range(n):
    term*=nums[i]
    if term>max:  
        max=term     
    if nums[i]==0:
        term=1
term=1
i=n-1
while i>=0:
    term*=nums[i]
    if term>max:
        max=term
    if nums[i]==0:
        term=1
    i-=1
return max

7.四数之和
思路:数组先排序,固定两个数,再用双指针记录低位,高位。结果比目标大,高位减一,结果比目标小,低位加一。 最后利用元组去重转化为列表。

nums.sort()
ans=set()  
for i in range(len(nums)-3):
     for j in range(i+1,len(nums)-2):#固定两个数
        left=j+1#左指针
        right=len(nums)-1#右指针
        while(right>left):
            temp=nums[i]+nums[j]+nums[left]+nums[right]
            if temp==target:
                ans.add((nums[i],nums[j],nums[left],nums[right]))
                left+=1
                right-=1
            if temp>target:right-=1#太大了,右指针左移
            if temp<target:left+=1#反之
#去重
rec=[]
for i in ans:
    rec.append(list(i))
return rec

8.重复的数
思路1:根据列表转化为数组后的长度是否有变化来判断

if len(set(nums))==len(nums):
    return False
else:
    return True

思路2:列表记录当前走过的数据(空间复杂度高)

l=[]
false =False
true =True
n=len(nums)
for i in range(n):
    if nums[i] not in l:
        l.append(nums[i])
    else:
        return true
    return false

9.翻转数组
给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
思路:先对k取余,确保k不会大于数组长度;如果k值为0相当于数组无变化。否为整体变换。

k=k%len(nums)
if k==0:
    return nums
else:
    temp = nums[len(nums) - k:]      
    nums[k:] = nums[:len(nums) - k]     
    nums[:k] = temp 
    return nums

10.旋转数组的最小数字(剑指offer第11题)
输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。

lis=[int(n) for n in input("").split()]
if len(lis)==0:
    print(0)
for i in range(len(lis)-1):
   if lis[i]>lis[i+1]:
        min=lis[i+1]
print(min)

11.移动0
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
思路1:遍历一遍数组,如果值为0,后面的数值整体前移一位,并记录0出现的次数;否则继续遍历下一位。最后根据0出现的次数,对最后的几位数字赋予0的值。

k=0
i=0
while i<len(nums)-k:
    if nums[i]==0:
        for j in range(i,len(nums)-1):
            nums[j]=nums[j+1]
        k+=1
    else:
        i+=1
for i in range(len(nums)-k,len(nums)):
    nums[i]=0
return nums

12.数组中重复的数字(剑指offer3题)
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
思路1:排序后 前后位置如果相同则为重复。时间复杂度nlogn
思路2:如果数组无重复数字,排序后数字i出现在坐标i中。从头到尾扫描数字,如果数字nums[i]不在i上,则和num[nums[i]]做交换,把nums[i]放到它的位置上,知道i==nums[i],继续遍历。假如nums[i]==nums[nums[i]]则重复,即找到数字。

思路2代码:
nums = [int(n) for n in input().split(" ")]
tar=0
for i in range(len(nums)):
    while nums[i]!=i:
        if nums[i]==nums[nums[i]]:
            tar=nums[i]
            break
        else:
            nums[nums[i]], nums[i]=nums[i],nums[nums[i]]
print(tar)

变形:不修改数组找出重复的数字
思路:二分法 每次遍历数组找每个low-middle的数字个数。大于数量M则在这个子区间,不大于则在另外一个子区间。 当low==high时退出。

lis = [2,3,5,4,3,3,6,7]
low = 1
high = max(lis)
while low <= high:
    mid = int((high - low) / 2) + low
    count1 = 0
    count2 = 0
    for i in range(len(lis)):
        if lis[i] >= low and lis[i] <= mid:
            count1 += 1
        if lis[i] > mid and lis[i] <=high:
            count2 += 1
    if low==high:
        break
    if count1 > mid - low+1:
        high = mid
    else:
        low = mid+1
print(low)

13.二维数组中的查找(剑指offer第4题)
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
思路:从左下角开始查找,往右是递增的,往上是递减的。如果目标值小于目前值,指标上移;如果目标值大于目前值,指标右移。

n=len(array)
m=len(array[0])
i=n-1
j=0
while i>=0 and j<m:
    if array[i][j]==target:
        return True
    elif array[i][j]>target:
        i-=1
        continue
    elif array[i][j]<target:
        j+=1
        continue
return False

14.调整数组顺序使奇数位于偶数前面(剑指offer21题)
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。
思路:双指针,前面不为偶数则指针一直后移,后面不为奇数则指针一直前移,然后交换两位置的数字。 注意:控制指针越界。

nums = [int(n) for n in input().split()]
low=0
high=len(nums)-1
while low<high:
    while nums[low]%2!=0:
        low+=1
        if low==high:
            break
    if low==high:
        break
    while nums[high]%2==0:
        high-=1
        if low==high:
            break
    if low==high:
        break
    nums[low], nums[high] = nums[high], nums[low]
    low+=1
    high-=1
print(nums)

15.把数组排成最小的数(剑指offer第45题)
输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。
思路:先定义一个两两比较的函数,判断哪种方式可以使得数字最小。 然后使用排序算法进行排序,只是原来比较数值大小,现在比较拼接方式大小。最后使用一个字符串依次拼接排好序的数字。

def compare(num1, num2):
    s1=str(num1)
    s2=str(num2)
    count1=int(s1+s2)
    count2=int(s2+s1)
    if count1>=count2:
        return True
    else:
        return False
def minNumber(nums):
    for i in range(len(nums)-1):
        for j in range(len(nums)-1-i):
            if self.compare(nums[j], nums[j+1]):
                nums[j], nums[j+1]= nums[j+1],nums[j]
    s=""
    for i in range(len(nums)):
        s+=str(nums[i])
    return s

16.子数组合并 判断最多能实现多少次合并操作?(美团笔试)
例[1,1,1,1]->[2,1,1] 遍历数组,相同则操作+1,继续递归。函数返回值为每个长度数组下的最多合并操作次数。

def get_count(lis):
    n=len(lis)
    max=0
    for i in range(n-1):
        count=0
        if lis[i]==lis[i+1]:
            p =lis[:i]+[lis[i]+1]+lis[i+2:]
            count=get_count(p)+1
            if count>max:
                max=count
    return max
print(get_count(lis))

17. O(N)时间找到数组第K大的数
思路:快排 确定位置。

#定义快排思路函数
def patt(lis, low, high):
    while low<high:
        while low<high and lis[low] < lis[high]:
            high -= 1
        if low<high:
            lis[high], lis[low] = lis[low], lis[high]
        while lis[low] < lis[high]:
            low += 1
        if low<high:
            lis[low], lis[high] = lis[high], lis[low]
    return low

lis = [2, 4, 6, 7]
K = 1
low = 0
high = len(lis)-1
k = len(lis) - K
mid = patt(lis, low, high)
while(mid != k):
    if mid <k:
        mid = patt(lis, mid+1, high)
    else:
        mid = patt(lis, low, mid-1)
print(lis[mid])
  1. 原地删除排序数组的元素 快指针遍历数组 记录不一样的数字 到slow中
if len(s)==0:
    print(0)
slow = 1
for quick in range(1, len(s)):
    if s[quick]!=s[quick-1]:
        s[slow]=s[quick]
        slow += 1
print(slow)
  1. 寻找数组的中心‘索引’
s =[8,15,2,2,7,16]
sum=0
for i in range(len(s)):
    sum+=s[i]
total = 0
for i in range(len(s)):
    total += s[i]
    sum -= s[i]
    if total == sum:
        print(i)