数组中的逆序对
题目描述
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
输入描述:
题目保证输入的数组中没有的相同的数字
数据范围:
对于%50的数据,size<=10^4
对于%75的数据,size<=10^5
对于%100的数据,size<=2*10^5
解题思路:
法一:(未通过)
先将原序列排序,然后从排完序的数组中取出最小的,它在原数组中的位置表示有多少比它大的数在它前面,每取出一个在原数组中删除该元素,保证后面取出的元素在原数组中是最小的,这样其位置才能表示有多少比它大的数在它前面,即逆序对数。
法二:(通过)
用归并排序,归并排序能够有效的减少最坏时间复杂度,但是它有额外的开销,以空间换时间。把原数据分成两个数组,每次取两个数组中的最小值放入一个新的数组中,直到其中一个数组全部取完。
代码:
法一:
# -*- coding:utf-8 -*-
class Solution:
def InversePairs(self, data):
# write code here
copy =[]
count =0
for i in data:
copy.append(i)
copy.sort()
for i in range(len(copy)):
count += data.index(copy[i])
data.remove(copy[i])
return count %1000000007
法二:
# -*- coding:utf-8 -*-
class Solution:
def InversePairs(self, data):
# write code here
length = len(data)
if data == None or length <=0:
return 0
copy = [0]*length
for i in range(length):
copy[i] = data[i]
count = self.InversePairsCore(data,copy,0,length-1)
return count%1000000007
def InversePairsCore(self, data, copy, start, end):
if start == end:
copy[start] = data[start]
return 0
length = (end-start)//2
left = self.InversePairsCore(copy, data, start, start+length)
right = self.InversePairsCore(copy, data, start+length+1, end)
i = start +length
j = end
indexCopy = end
count = 0
while i >=start and j>=start+length+1:
if data[i]>data[j]:
copy[indexCopy] = data[i]
indexCopy -=1
i -= 1
count +=j-start-length
else:
copy[indexCopy]=data[j]
indexCopy -= 1
j -=1
while i>=start:
copy[indexCopy] = data[i]
indexCopy-=1
i-=1
while j>=start+length+1:
copy[indexCopy] = data[j]
indexCopy -= 1
j-=1
return left+right+count
两个链表的第一个公共结点
题目描述
输入两个链表,找出它们的第一个公共结点。
解题思路:(真的很奇妙~)
共同节点,意味着从共同节点开始之后所有的节点数都是相同的,这是链表,只要有一个共同节点,那么之后所有的指向
也是重复的。
先依次遍历两个链表,记录两个链表的长度m和n,如果 m > n,那么我们就先让长度为m的链表走m-n个结点,然后两个链表同时遍历,当遍历到相同的结点的时候停止即可。对于 m < n,同理。
代码:
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def FindFirstCommonNode(self, pHead1, pHead2):
# write code here
Length1 = self.GetLength(pHead1)
Length2 = self.GetLength(pHead2)
LengthDiff = abs(Length1- Length2)
if Length1>Length2:
pHeadLong = pHead1
pHeadShort = pHead2
else:
pHeadLong = pHead2
pHeadShort = pHead1
for i in range(LengthDiff):
pHeadLong = pHeadLong.next
while pHeadLong != None and pHeadShort != None and pHeadLong != pHeadShort:
pHeadLong = pHeadLong.next
pHeadShort = pHeadShort.next
return pHeadLong
def GetLength(self, pHead):
length = 0
while pHead:
pHead = pHead.next
length += 1
return length
数字在排序数组中出现的次数
题目描述
统计一个数字在排序数组中出现的次数。
解题思路:
法一:count函数是顺序查找,最坏时间复杂度是O(n)
法二:
看见有序就要想起使用二分法查找,最坏时间复杂度是O(logn)
对于一个有序数组,要考虑 1,2,2,2,3,4这种情况,计算k=2在数组中出现的次数,用二分法去找这个数,一个找最前面
出现的2的下标,一个找最后面2出现的小标,这样前后相减+1即可得到结果。
代码:
法一:
# -*- coding:utf-8 -*-
class Solution:
def GetNumberOfK(self, data, k):
# write code here
return data.count(k)
法二:
# -*- coding:utf-8 -*-
class Solution:
def GetNumberOfK(self, data, k):
# write code here
number = 0
if data != None and len(data)>0:
length = len(data)
First = self.GetFirst(data, length, k,0,length-1)
Last = self.GetLast(data, length, k, 0, length-1)
if First > -1:
number = Last-First +1
return number
def GetFirst(self, data, length, k, start, end):
if start > end:
return -1
middle = (start+end)//2
if data[middle]==k:
if middle>0 and data[middle-1]==k:
end = middle-1
else:
return middle
elif data[middle]>k:
end = middle-1
else:
start = middle+1
return self.GetFirst(data, length, k, start, end)
def GetLast(self, data, length, k, start, end):
if start> end:
return -1
middle = (start+end)//2
if data[middle]==k:
if middle<end and data[middle+1]==k:
start = middle+1
else:
return middle
elif data[middle]>k:
end = middle-1
else:
start = middle+1
return self.GetLast(data, length, k, start, end)