Theory
希尔排序本质上是对插入排序的一种优化,它利用了插入排序的简单,又克服了插入排序每次只交换相邻两个元素的缺点。它的基本思想是:
将待排序数组按照一定的间隔分为多个子数组,每组分别进行插入排序。这里按照间隔分组指的不是取连续的一段数组,而是每跳跃一定间隔取一个值组成一组
逐渐缩小间隔进行下一轮排序
最后一轮时,取间隔为 1,也就相当于直接使用插入排序。但这时经过前面的「宏观调控」,数组已经基本有序了,所以此时的插入排序只需进行少量交换便可完成
增量序列
上文说到,增量序列的选择会极大地影响希尔排序的效率。增量序列如果选得不好,希尔排序的效率可能比插入排序效率还要低,举个例子:
在这个例子中,我们发现,原数组 8 间隔、4 间隔、2 间隔都已经有序了,使用希尔排序时,真正起作用的只有最后一轮 1 间隔排序,也就是直接插入排序。希尔排序反而比直接使用插入排序多执行了许多无用的逻辑。
LC 912. 排序数组
class Solution:
def sortArray(self, nums: List[int]) -> List[int]:
b = len(nums)
gap = b // 2
while gap > 0:
for i in range(gap, b):
temp = nums[i]
j = i
while j >= gap and nums[j - gap] > temp:
nums[j] = nums[j - gap]
j -= gap #decrements j by gap to move backwards in
#the list and contine comparing elements gap distance apart
nums[j] = temp #once the correct position for the temp element
#is found, temp is inserted into the list at the current position of j
gap //= 2 #After each pass through the list with a given gap, the gap is halved.
return nums
LC 506. 相对名次
给你一个长度为 n 的整数数组 score ,其中 score[i] 是第 i 位运动员在比赛中的得分。所有得分都 互不相同 。
运动员将根据得分 决定名次 ,其中名次第 1 的运动员得分最高,名次第 2 的运动员得分第 2 高,依此类推。运动员的名次决定了他们的获奖情况:
名次第 1 的运动员获金牌 "Gold Medal" 。
名次第 2 的运动员获银牌 "Silver Medal" 。
名次第 3 的运动员获铜牌 "Bronze Medal" 。
从名次第 4 到第 n 的运动员,只能获得他们的名次编号(即,名次第 x 的运动员获得编号 "x")。
使用长度为 n 的数组 answer 返回获奖,其中 answer[i] 是第 i 位运动员的获奖情况。
class Solution:
def findRelativeRanks(self, score: List[int]) -> List[str]:
n = len(score) # Get the length of the score list
gap = n // 2 # Initialize the gap for the Shell sort
# Shell sort implementation
while gap > 0:
for i in range(gap, n): # Start from 'gap' to the end of the list
temp = score[i] # Temporarily store the value at current index
j = i # Initialize 'j' with the current index 'i'
# Move elements that are 'gap' positions apart and greater than 'temp' to their correct positions
while j >= gap and score[j - gap] < temp: # Change the comparison to '<' for descending order
score[j] = score[j - gap] # Shift the score[j-gap] to the right
j -= gap # Move 'j' backwards by 'gap' positions
score[j] = temp # Place 'temp' in its correct position
gap //= 2 # Reduce the gap for the next pass
return score
first attempt:
套用上面的基础代码,加上case specific的ranking要求。
执行结果:解答错误
通过测试用例:3 / 18
class Solution:
def findRelativeRanks(self, score: List[int]) -> List[str]:
n=len(score)
gap = n//2
while gap >0:
for i in range(gap,n):
temp=score[i]
j=i
while j>= gap and score[j-gap]>temp:
score[j]=score[j-gap]
j-=gap
score[j]=temp
gap//=2
score_to_rank = {score[i]:i+1 for i in range(n)}
ranks=[""]*n
for i in range(n):
if score_to_rank[score[i]]==1:
ranks[i]="Gold Medal"
elif score_to_rank[score[i]]==2:
ranks[i]="Silver Medal"
elif score_to_rank[score[i]]==3:
ranks[i]='Bronze Medal'
else:
ranks[i]=str(score_to_rank[score[i]])
return ranks