已解答
中等
相关标签
相关企业
给你一个整数数组 arr
,请使用 煎饼翻转 完成对数组的排序。
一次煎饼翻转的执行过程如下:
- 选择一个整数
k
,1 <= k <= arr.length
- 反转子数组
arr[0...k-1]
(下标从 0 开始)
例如,arr = [3,2,1,4]
,选择 k = 3
进行一次煎饼翻转,反转子数组 [3,2,1]
,得到 arr = [1,2,3,4]
。
以数组形式返回能使 arr
有序的煎饼翻转操作所对应的 k
值序列。任何将数组排序且翻转次数在 10 * arr.length
范围内的有效答案都将被判断为正确。
示例 1:
输入:[3,2,4,1] 输出:[4,2,4,3] 解释: 我们执行 4 次煎饼翻转,k 值分别为 4,2,4,和 3。 初始状态 arr = [3, 2, 4, 1] 第一次翻转后(k = 4):arr = [1, 4, 2, 3] 第二次翻转后(k = 2):arr = [4, 1, 2, 3] 第三次翻转后(k = 4):arr = [3, 2, 1, 4] 第四次翻转后(k = 3):arr = [1, 2, 3, 4],此时已完成排序。
示例 2:
输入:[1,2,3] 输出:[] 解释: 输入已经排序,因此不需要翻转任何内容。 请注意,其他可能的答案,如 [3,3] ,也将被判断为正确。
提示:
1 <= arr.length <= 100
1 <= arr[i] <= arr.length
arr
中的所有整数互不相同(即,arr
是从1
到arr.length
整数的一个排列)
解题思路:
1、通过查看题目我们可知,最后的结果是将这个列表中的元素从小到大进行排序,这是我们做这道题目的关键点。
2、通过题目我们发现所谓的煎饼翻转就是:将索引在K值前面的元素倒序书写。完成这个功能我们可以使用一个for循环语句:for i in range(len(arr)),加上赋值语句:arr[i]=arr[num-i],其中num是题目中的k值。但是我们需要注意,在将一个列表中元素顺序重新排序时,显然需要一个临时列表作为缓冲,从而实现保护已经更改后的列表元素数据。翻转的代码如下:
def paixu(self,arr,num):
#实现根据索引排序功能
arr1=arr[:]
for i in range(len(arr)):
if i<=num:
arr[i]=arr1[num-i]
return arr
3.通过题目我们还可以知道若给定列表的元素是:按照从小到大的顺序或者列表元素都是相同的,则不需要进行翻转。所以我们在翻转操作前需要对列表元素进行检验,若列表元素规范,则不需要翻转,反之,则需要翻转。我的思路是:将给定的列表通过排序算法进行排序后,再与给定的列表进行比较,如果两者是相同的,则不需要翻转,返回[]。具体实现代码如下:
def maopao(self,arr):
for i in range(len(arr)):
for j in range(len(arr)-1):
if arr[j]>arr[j+1]:
tmp=arr[j]
arr[j]=arr[j+1]
arr[j+1]=tmp
return arr
#在进行翻转操作之前,执行检验语句
if arr1==maopao_arr:
return []
4.通过题目给出的实例代码我发现通过两次翻转就可实现将最大列表元素移动值最右边:
具体思路为:
①找到列表中最大元素对应的索引,将索引值加1作为题目中的k值。然后将列表和k值传入前文定义好的paixu(arr,k)函数中进行第一次翻转。同时将k追加保存到result空列表中。
②通过第一次翻转,得到的列表内容:可以发现列表中最大元素在列表的最左边,所以我们只要将第一次的翻转结果,作为第二次翻转的输入列表,并且k值传入列表的长度。同时将k追加保存到result空列表中。可以使用len函数。
最后通过两次翻转后我们就实现了将列表中最大元素移动到列表的最右边。此时我们将得到的列表中最大值删除后(通过remove函数),得到的列表作为下一轮第一次翻转的输入列表即可,然后又第一次翻转后的列表作为第二次翻转函数的输入.....依次类推,即可解决问题。
以下是我的代码分享:
class Solution(object):
def paixu(self,arr,num):
#实现根据索引排序功能
arr1=arr[:]
for i in range(len(arr)):
if i<=num:
arr[i]=arr1[num-i]
return arr
def maopao(self,arr):
for i in range(len(arr)):
for j in range(len(arr)-1):
if arr[j]>arr[j+1]:
tmp=arr[j]
arr[j]=arr[j+1]
arr[j+1]=tmp
return arr
def maxindex(self,arr):
#获取给定列表中的最大值索引
return arr.index(max(arr))
def pancakeSort(self, arr):
result=[] #存储返回结果
arr2=[] #存储将最大列表元素放在最右边后的列表
arr1=arr[:] #将arr的内容复制到arr1中
arr3=arr[:] #存储去掉最大值后的列表
arr4=[] #用于存储排完序的结果
print(arr1) #输出当前传入函数的列表内容
tmp=0
maopao_arr=self.maopao(arr)
print(maopao_arr,arr1)
if arr1==maopao_arr:
return []
for i in range(len(arr1)):
lenth_arr=len(arr3) #获取当前列表的长度
print("arr3的列表内容为:",arr3)
tmp=max(arr3) #获取列表arr3中的最大值
max_index=self.maxindex(arr3) #获取arr3中最大列表元素对应的索引
print("列表中最大值的索引为:",max_index)
tmp_arr=arr3[:]#临时列表,保存第一次翻转内容传输给第二次翻转内容
if max_index==lenth_arr: #如果列表中最大值已经在最右边,则去掉最大值即可
arr3.remove(tmp)
continue
elif (lenth_arr!=1): #如果还有一个列表元素,则不需要翻转
if max_index!=0 and max_index!=lenth_arr-1: #如果次大的元素已经在列表索引为0处,则不进行翻转
result.append(max_index+1)
tmp_arr=self.paixu(arr3,max_index)
print("经过一次排序后输出结果为",tmp_arr,"保存的k值为:",max_index+1)
print("最大索引和列表长度",max_index,lenth_arr)
if max_index==lenth_arr-1:
print("huqinsong")
arr3.remove(tmp)
continue
if lenth_arr-1!=max_index: #如果列表中次大in列表元素与最大元素相邻,则不进行翻转
result.append(lenth_arr)
print(tmp_arr,lenth_arr-1)
arr2=self.paixu(tmp_arr,lenth_arr-1)
print("经过两次排序输出结果为:",arr2,"保存ink值为:",lenth_arr)
arr2.remove(tmp) #去掉列表中最大值
arr4.append(tmp)
arr3=arr2[:]
print("去掉表中最大值后列表内容:",arr3)
print("\n")
continue
else:
arr4.append(arr3[0])
continue
print("result列表中内容为:",result)
print("排好序后in结果为:",arr4)
return result
arr=[3,2,4,1]
s=Solution()
s.pancakeSort(arr)
# 4 2 3 1 (3)
# 1 3 2 4 (4)
# 3 1 2 4 (2)
# 2 1 3 4 (3)
#1 2 3 4 (2)
力扣运行通过截图: