今天面试看到一道算法题(手写),咋一看很简单,思路也立马闪现到脑海中,但总感觉哪个解法绝对不是最优的
题目意思大概是这样的,有这样一个序列st = [-22, -3, -5, 11, 12, -4, 13, 24, -9],对它进行排序,要求1.负数在前,整数在后;2.在满足1的条件下要保证偶数在前,奇数在后。
第一眼看到这个题目,思路就有了(我知道肯定不是最优的,但是时间有限,先做出来再说)
思路一、简单粗暴,肯定先处理正负,再处理奇偶
def ji_ou_check(arr):
ji_list, ou_list = list(), list()
for i in arr:
if i % 2 == 0:
ou_list.append(i)
else:
ji_list.append(i)
return ou_list + ji_list
st = [-22, -3, -5, 11, 12, -4, 13, 24, -9]
def fa1(arr):
fu_list,zh_list = list(),list()
for i in st:
if i < 0:
fu_list.append(i)
else:
zh_list.append(i)
return ji_ou_check(fu_list) + ji_ou_check(zh_list)
result1 = fa1(st)
print(result1,'----------method1-----------')
这个思路虽然简单易懂,但是这个过程中除了st外,额外增加了4个列表,看到这个,我当时心里有点发怵,算了,时间要紧,先这样吧
思路二、虽然总体原则也是先处理正负,再处理奇偶,但是思路二,除了本身的st外,没有多余产生一个新的list
1、既然所排列表中,即有正也有负数,那么我们何不直接先对整个列表进行排序,这样要去,正的一部分和负的一部分起步容易的很
2、在1.的基础之上利用切片,将正负分开
def fa2(arr):
arr.sort()
temp=0
for index,i in enumerate(arr):
if i>0:
temp=index
break
before=ji_ou_check_plus(arr[:temp])
rear=ji_ou_check_plus(arr[temp:])
return before+rear
3.在2中我们已经对正负做了处理,接下来就是处理奇偶的问题了,在这里我处理奇偶的话,主要是利用了列表的下标,原则是要想偶数在前,那么我们只需要保证偶数位的小标始终都比第一个奇数的下标小即可,根据此想法可以有如下代码
def flag_fun(arr):
flag=0
for index, i in enumerate(arr):
if i%2!=0:
flag=index
break
return flag
def ji_ou_check_plus(arr):
for index ,i in enumerate(arr):
flag=flag_fun(arr)
if i%2==0 and index>flag:
arr[index],arr[flag]=arr[flag],arr[index]
return arr
其实这道算法题,我觉得只要稍加修改就可以成为一道新的题目
思路三、头尾指针移动法
def plus(array):
head = 0
tail = len(array) - 1
while head < tail:
while head < tail and array[head] % 2 == 0:
head += 1
while head < tail and array[tail] % 2 != 0:
tail -= 1
if head < tail:
array[tail], array[head] = array[head], array[tail]
return array
print(plus([-22, -3, -5, 11, 12, -4, 13, 24, -9]))