1 题目描述
给定一个非负整数数组 A, A 中一半整数是奇数,一半整数是偶数。
对数组进行排序,以便当 A[i] 为奇数时,i 也是奇数;当 A[i] 为偶数时, i 也是偶数。
你可以返回任何满足上述条件的数组作为答案。
输入:[4,2,5,7]
输出:[4,5,2,7]
解释:[4,7,2,5],[2,5,4,7],[2,7,4,5] 也会被接受。
提示
2 <= A.length <= 20000
A.length % 2 == 0
0 <= A[i] <= 1000
2 题解
数组肯定是偶数长,当出现奇偶不配,肯定是成对的出现,例如有3个奇数在偶数位的,肯定会有3个偶数在奇数位的。
很明显的一个双指针问题。
2.1 双指针
维护两个指针i和j,i从前面开始扫描,寻找奇数在偶数位的,j逆向扫描,寻找偶数在奇数位的,swap.
class Solution:
def sortArrayByParityII(self, A):
nums_len = len(A)
i, j = 0, nums_len - 1
while i < nums_len and j > -1:
""" 奇数在偶数位 """
while i < nums_len:
if A[i] % 2 == 1 and i % 2 == 0:
break
i += 1
""" 偶数在奇数位 """
while j > -1:
if A[j] % 2 == 0 and j % 2 == 1:
break
j -= 1
if i < nums_len and j > -1:
A[i], A[j] = A[j], A[i]
return A
def main(self):
nums = [4, 2, 5, 7]
print(self.sortArrayByParityII(nums))
if __name__ == '__main__':
solution = Solution()
solution.main()
改进:
在前面中我们呢每次下标都是跳一步,实际上一个奇数它的下一个连续奇数得跳两步,偶数也是
def sortArrayByParityII(self, A):
nums_len = len(A)
i, j = 0, nums_len - 1
while i < nums_len and j > -1:
""" 奇数在偶数位 """
while i < nums_len:
if A[i] & 1:
break
i += 2
""" 偶数在奇数位 """
while j > -1:
if not A[j] & 1:
break
j -= 2
if i < nums_len and j > -1:
A[i], A[j] = A[j], A[i]
return A
2.2 空间换时间
我们可以开辟一个len(A)的list,不修改原数组,遇见偶数放偶数位,遇见奇数放奇数位。
def method2(self, nums):
res = [0 for _ in range(len(nums))]
odd_index = 1
even_index = 0
for val in nums:
if val & 1 == 1:
res[odd_index] = val
odd_index += 2
else:
res[even_index] = val
even_index += 2
return res
2.3 python那些骚操作
空间和时间效率都很低,重点在于掌握,zip、reduce
函数得使用。
def method3(self, nums):
odd = [i for i in nums if i & 1]
even = [i for i in nums if not i & 1]
from functools import reduce
return reduce(lambda x, y: x + y, ([i, j] for i, j in zip(even, odd)))