牛客刷题day9
文章目录
1.排序
题目
给定一个数组,请你编写一个函数,返回该数组排序后的形式。
解题思路
关于排序,请看专题排序专栏
核心代码
关于排序代码,请看专题排序专栏
2.寻找峰值
题目
山峰元素是指其值大于或等于左右相邻值的元素。给定一个输入数组nums,任意两个相邻元素值不相等,数组可能包含多个山峰。找到索引最大的那个山峰元素并返回其索引。
假设 nums[-1] = nums[n] = -∞。
输入:[2,4,1,2,7,8,4]
返回值:5
解题思路
因为要求索引值最大的峰值,所以从末尾遍历数组,找到的第一个符合条件的值即索引最大。
核心代码
class Solution:
def solve(self , a ):
# write code here
len_a = len(a)
for i in range(len_a-1,-1,-1):
if a[i]>a[i-1]:
return i
3.求平方根
题目
实现函数 int sqrt(int x).
计算并返回x的平方根(向下取整)
解题思路
二分法
核心代码
class Solution:
def sqrt(self, x):
if x <= 1: return x
left = 1
right = x
while left <= right:
mid = left + (right - left) // 2
if mid * mid > x:
right = mid - 1
elif mid * mid < x:
left = mid + 1
else:
return mid
return right
4.合并K个已排序的链表
题目
合并 k 个已排序的链表并将其作为一个已排序的链表返回。分析并描述其复杂度。
输入:[{1,2,3},{4,5,6,7}]
返回值:{1,2,3,4,5,6,7}
解题思路
1.递归解决
这道题目最容易想到的做法是,使用合并两个有序链表中的方法,合并两个有链表,融合前两个链表,将下一个链表与当前结果融合,遍历列表中的每个链表,不断循环下去。但是这种方法时间复杂度很高,我们考虑用二分法把列表进行中间拆分,将列表都拆成长度相等的两个列表,然后融合每个小列表中的链表即可。这样就可以将K级别的融合计算量转换为log(K)级别。
2.最小堆
主要是利用最小堆方法,用一个大小为K的最小堆(用优先队列+自定义降序实现)(优先队列就是大顶堆,队头元素最大,自定义为降序后,就变成小顶堆,队头元素最小),先把K个链表的头结点放入堆中,每次取堆顶元素,然后将堆顶元素所在链表的下一个结点加入堆中
核心代码
1.递归解决
class Solution:
# 将链表拆分成两个长的链表,递归拆分
def mergeKLists(self, lists):
lenLists = len(lists)
if lenLists == 0:
return None
if lenLists == 1:
return lists[0]
if lenLists == 2:
return self.mergeTwoLists(lists[0], lists[1])
mid = lenLists // 2
left = self.mergeKLists(lists[:mid])
right = self.mergeKLists(lists[mid:])
return self.mergeTwoLists(left, right)
# 将两个链表合成一个链表
def mergeTwoLists(self, list1, list2):
if not list1:
return list2
if not list2:
return list1
mergeTwoList = ListNode(0)
res = mergeTwoList
while list1 and list2:
if list1.val <list2.val:
mergeTwoList.next =list1
mergeTwoList = mergeTwoList.next
list1 = list1.next
else:
mergeTwoList.next = list2
mergeTwoList = mergeTwoList.next
list2 = list2.next
if list1:
mergeTwoList.next = list1
if list2:
mergeTwoList.next =list2
return res.next
2.最小堆
class Solution:
def mergeKLists(self, lists: List[ListNode]) -> ListNode:
import heapq
dump= ListNode(0)
p = dump
head = []
#首先将每个链表表头放入最小堆中
for i in range(len(lists)):
if lists[i] :
heapq.heappush(head, (lists[i].val, i))
lists[i] = lists[i].next
while head:
val, idx = heapq.heappop(head)
#取出最小堆的值,放在链表第一位
p.next = ListNode(val)
p = p.next
# 将取出链首元素新链表链首放入堆中,直到堆为空
if lists[idx]:
heapq.heappush(head, (lists[idx].val, idx))
lists[idx] = lists[idx].next
return dump.next
5.字符串的排列
题目
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则按字典序打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
输入描述:
输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。
示例1
输入 “ab” 返回值 [“ab”,“ba”]
解题思路
1.递归解决
2.python 自带库itertools.permutations
核心代码
1.基于回溯思想
class Solution:
def Permutation(self, ss):
# write code here
res = []
if len(ss) == 0:
return []
if len(ss) == 1:
return [ss]
self.helper(ss, res, '')
return sorted(list(set(res)))
def helper(self, ss, res, path):
if len(ss) == 1:
res.append(path + ss[0])
else:
for i in range(len(ss)):
self.helper(ss[:i] + ss[i + 1:], res, path + ss[i])
2.python自带库
import itertools
class Solution:
def Permutation(self, ss):
# write code here
if not ss:
return []
arr = sorted(set(list(map(''.join,itertools.permutations(ss)))))
return arr
6.输出二叉树右视图
题目
请根据二叉树的前序遍历,中序遍历恢复二叉树,并打印出二叉树的右视图
输入
[1,2,4,5,3],[4,2,5,1,3]
返回值
[1,3,5]
解题思路
本题总体可拆分为两部分:
根据先序、中序遍历重构二叉树
层序遍历二叉树输出每层最右侧元素
核心代码
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution:
def solve(self, xianxu, zhongxu):
root = self.buildTree(xianxu, zhongxu)
return self.printRightTree(root)
def buildTree(self, xianxu, zhongxu):
if len(xianxu) < 1 and len(zhongxu) < 1:
return None
root = TreeNode(xianxu[0])
root_index = zhongxu.index(root.val)
root.left = self.buildTree(xianxu[1:root_index + 1], zhongxu[:root_index])
root.right = self.buildTree(xianxu[root_index + 1:], zhongxu[root_index + 1:])
return root
def printRightTree(self,root):
res =[]
queue =[root]
while queue:
curLevel=[]
nextLevel =[]
for node in queue:
curLevel.append(node.val)
if node.left:
nextLevel.append(node.left)
if node.right:
nextLevel.append(node.right)
queue=nextLevel
res.append(curLevel[-1])
return res
7.单链表的排序
题目
给定一个无序单链表,实现单链表的排序(按升序排序)。
输入:[1,3,2,4,5]
返回值:{1,2,3,4,5}
解题思路
1.常规思路
先将链表转为数组,对数组进行排序,最后再将已经排序的数组转成链表
2.利用归并排序
首先使用快慢指针,把链表切割成两部分。然后在递归调用将单链表切分成单个单个的结点
最后好戏上场,逐个的去拼接left 和 right 递归回来的链表,按照从小到大从左到右的 顺序把 链表拼接上去
核心代码
1.常规思路
class Solution:
def sortInList(self , head ):
# write code here
if not head:
return head
cur =head
valList =[]
while cur:
valList.append(cur.val)
cur = cur.next
valList.sort()
List = ListNode(0)
p=List
for i in valList:
node =ListNode(i)
p.next = node
p = p.next
return List.next
2.归并排序
class Solution:
def sortInList(self , head ):
if head is None&nbs***bsp;head.next is None:
return head
# cut is used to cut down list
cut = head
# use
slow = head
fast = head
# find mid node
while fast and fast.next:
cut = slow
slow = slow.next
fast = fast.next.next
left = head
right = cut.next
cut.next = None
left = self.sortInList(left)
right = self.sortInList(right)
return self.merge(left, right)
def merge(self, left, right):
guard = ListNode(0)
p = guard
while left and right:
if left.val < right.val:
guard.next = left
left = left.next
else:
guard.next = right
right = right.next
guard = guard.next
# append remain list
if left:
guard.next = left
if right:
guard.next = right
return p.next
8.出现次数top K的问题
题目
给定String类型的数组strArr,再给定整数k,请严格按照排名顺序打印 出次数前k名的字符串。
如果strArr长度为N,时间复杂度请达到O(N \log K)O(NlogK)
输出K行,每行有一个字符串和一个整数(字符串表示)。
你需要按照出现出现次数由大到小输出,若出现次数相同时字符串字典序较小的优先输出
解题思路
创建字典,用字典存储数组元素出现的次数
然后对字典根据出现的次数进行排序,最后根据条件将k个元素输出
核心代码
class Solution:
def topKstrings(self , strings , k ):
# write code here
hashTable = dict()
for s in strings:
if s in hashTable:
hashTable[s] += 1
else:
hashTable[s] = 1
res = []
for key, value in sorted(hashTable.items(), key = lambda kv:(-kv[1], kv[0]))[:k]:
res.append([key, value])
return res
写在后面
博主创作不易,无论是找资料还是写代码都是需要花费时间和精力的,茫茫人海,如果你看到了我的博客,觉得写的还行的话,希望能点赞支持一下,让我更有创作的动力。