第33题:丑数
题目说明:把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
程序:
丑数可以分解成:2 ^ x * 3 ^ y * 4 ^ z
1*(2, 3, 5)=2, 3, 5; 2*(2, 3, 5)=4, 6, 10; 3*(2, 3, 5)=6, 9, 15…
# -*- coding:utf-8 -*-
class Solution:
def GetUglyNumber_Solution(self, index):
# write code here
if index <= 0:
return 0
result = [1]
twoIndex = 0
threeIndex = 0
fiveIndex = 0
for i in range(index-1):
uglyNumber = min(result[twoIndex]*2, result[threeIndex]*3, result[fiveIndex]*5)
result.append(uglyNumber)
if uglyNumber % 2 == 0:
twoIndex += 1
if uglyNumber % 3 == 0:
threeIndex += 1
if uglyNumber % 5 == 0:
fiveIndex += 1
return result[-1]
知识点:
判断一个数是否是丑数
def IsUglyNumber(self, number):
if number == 1:
return True
if (number / 2) == 1 or (number / 3) == 1 or (number / 5) == 1 :
return True
else:
if number % 2 == 0:
return self.IsUglyNumber(number / 2)
elif number % 3 == 0:
return self.IsUglyNumber(number / 3)
elif number % 5 == 0:
return self.IsUglyNumber(number / 5)
else:
return False
第34题:第一个只出现一次的字符
题目说明:在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写)
程序:
# -*- coding:utf-8 -*-
class Solution:
def FirstNotRepeatingChar(self, s):
# write code here
if not s:
return -1
for i in range(len(s)):
if s.count(s[i]) == 1:
return i
return -1
第35题:数组中的逆序对
题目说明:在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
输入描述:
题目保证输入的数组中没有的相同的数字
数据范围:
对于%50的数据,size<=10^4
对于%75的数据,size<=10^5
对于%100的数据,size<=2*10^5
示例1
输入
复制
1,2,3,4,5,6,7,0
输出
复制
7
程序:
归并排序:[A+B]的逆序对 = [A]的逆序对 +[B]的逆序对 + 将A、B混排在一起的逆序对
# -*- coding:utf-8 -*-
class Solution:
def InversePairs(self, data):
# write code here
count, result = self.merge_sort(data)
return count%1000000007
def merge_sort(self, a_list):
n = len(a_list)
count = 0
if n <= 1:
return count, a_list
# 拆分
count_l, left = self.merge_sort(a_list[:n // 2])
count_r, right = self.merge_sort(a_list[n // 2:])
# 合并排序
count_merge, merge = self.merge(left, right)
count = count_l + count_r + count_merge
return count, merge
def merge(self, left, right):
count = 0
l = r = 0
result = []
while l < len(left) and r < len(right):
if left[l] <= right[r]:
result.append(left[l])
l += 1
else:
result.append(right[r])
r += 1
# 当右边的元素被插入时,证明这个元素比左边的剩下的所有元素都小
# 可以组成len(left)-l个逆序对
count += len(left) - l
result += left[l:] + right[r:]
return count, result
知识点:
1.暴力解法:时间复杂度为O(n^2)
# -*- coding:utf-8 -*-
class Solution:
def InversePairs(self, data):
# write code here
if not data:
return
sum = 0
for i in range(len(data) - 1):
for j in range(i+1, len(data)):
if data[i] > data[j]:
sum += 1
return (sum % 1000000007)
2.先将原数组复制,然后排序,从该数组中依次从前往后取元素,所取元素在原数组中的位置表示有多少比它大的数在它的前面,即逆位序,需保证每取出一个元素,原数组中删除该元素,这样,后面取出的元素在原数组中是最小。但是,这种方法使用remove()函数,remove()时间复杂度是O(n),那么,总的时间复杂度是O(n^2)。
# -*- coding:utf-8 -*-
class Solution:
def InversePairs(self, data):
# write code here
copy = [i for i in data]
count = 0
copy.sort()
for i in range(len(copy)):
count += data.index(copy[i])
data.remove(copy[i])
return count % 1000000007
第36题:两个链表的第一个公共结点
题目说明:输入两个链表,找出它们的第一个公共结点。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的)
程序:
什么是公共结点?
两个链表从某一结点开始,它们的next都指向同一个结点,由于是单链表,所以从第一个公共结点开始,之后两个链表的所有结点都是重合的。
首先遍历两个链表,分别得到两个链表的长度len1和len2;然后第二次遍历,在较长的链表上先走|len1-len2|步,接着同时在两个链表进行遍历,找到的第一个相同结点就是它们的第一个公共结点。
# -*- 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
if not pHead1 and not pHead2:
return None
len1 = 0
p1 = pHead1
while p1:
len1 += 1
p1 = p1.next
len2 = 0
p2 = pHead2
while p2:
len2 += 1
p2 = p2.next
p1 = pHead1
p2 = pHead2
if len1 == len2:
while p1 and p2:
if p1.val == p2.val:
return p1
else:
p1 = p1.next
p2 = p2.next
if len1 > len2:
for i in range(len1-len2):
p1 = p1.next
while p1 and p2:
if p1.val == p2.val:
return p1
else:
p1 = p1.next
p2 = p2.next
if len1 < len2:
for i in range(len2-len1):
p2 = p2.next
while p1 and p2:
if p1.val == p2.val:
return p1
else:
p1 = p1.next
p2 = p2.next
return None
# -*- 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
if not pHead1 and not pHead2:
return None
len1 = 0
p1 = pHead1
while p1:
len1 += 1
p1 = p1.next
len2 = 0
p2 = pHead2
while p2:
len2 += 1
p2 = p2.next
while len1 > len2:
pHead1 = pHead1.next
len1 -= 1
while len1 < len2:
pHead2 = pHead2.next
len2 -= 1
while pHead1 and pHead2:
if pHead1.val == pHead2.val:
return pHead1
else:
pHead1, pHead2 = pHead1.next, pHead2.next
return None