一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第15天,点击查看活动详情。
21、调整数组顺序使奇数位于偶数前面
输入一个整数数组,要求实现一个函数调整该数组中数字的顺序,使得数组的所有奇数在前半部分,数组的所有偶数在后半部分。
解题思路
我们可以使用双指针来解决本题,从前往后遍历数组,每次都判断属于奇数还是偶数,如果是奇数则从新的数组的前面开始插入,否则从新的数组的后面进行插入。最终返回新的数组即可,代码如下:
public int[] exchange(int[] nums) {
int len = nums.length;
int[] res = new int[len];
int left = 0;
int right = len - 1;
for(int i=0;i<len;i++){
if(nums[i] % 2 == 1){
res[left++] = nums[i];
}else {
res[right--] = nums[i];
}
}
return res;
}
上面的时间复杂度和空间复杂度都是,实际上空间可以进一步优化,优化思路如下:
可以从前往后找到第一个偶数和从后往前找到第一个奇数,之后交换位置即可,这样当left和right相遇时即数组遍历完毕,代码如下:
public int[] exchange(int[] nums) {
int len = nums.length;
int left = 0;
int right = len - 1;
while(left<right){
while(left<right&&nums[left]%2!=0) left++;
while(left<right&&nums[right]%2!=1) right--;
int temp = nums[left];
nums[left] = nums[right];
nums[right] = temp;
}
return nums;
}
此时空间复杂度就为。
22、链表中倒数第k个节点
给定一个链表,要求输出该链表的倒数第k个节点。
解题思路
简单的思路,首先计算链表的长度,之后再次遍历链表,返回链表的第个节点即可,代码如下:
public ListNode getKthFromEnd(ListNode head, int k) {
int len = 0;
ListNode cur = head;
while(cur!=null){
len ++;
cur = cur.next;
}
int curLen = 0;
while(head!=null){
if(curLen==len-k+1){
return head;
}
curLen++;
head = head.next;
}
return null;
}
时间复杂度。另外一种更简单的思路是使用快慢指针,我们可以让快指针先走k步,之后慢指针再和快指针一起走,最终返回慢指针即可:
public ListNode getKthFromEnd(ListNode head, int k) {
ListNode fast = head;
ListNode slow = head;
for(int i=0;i<k;i++){
fast = fast.next;
}
while(fast!=null){
fast = fast.next;
slow = slow.next;
}
return slow;
}