题目:
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
思路:
方法1
借用冒泡的思想,每两项比较,如果前偶后奇就交换。 复杂度为O(n^2)
方法2
空间换时间 ,新建一个数组,遍历给定数组,求出这个数组中的奇数的个数记作a,再遍历一遍数组,遇到奇数放a-1的前面,否则放后面。
方法3
插入排序的思想
代码:
public void reOrderArray(int[] array)
{
for (int i = 0; i < array.length; i++)
{
for (int j = 0; j < array.length - i - 1; j++)
{
if (array[j] % 2 == 0 && array[j + 1] % 2 != 0)
{
int a = array[j];
array[j] = array[j + 1];
array[j + 1] = a;
}
}
}
}
public void reOrderArray1(int[] array)
{
int num = 0;
for (int i = 0; i < array.length; i++)
{
if (array[i] % 2 == 1)
{
num++;
}
}
int[] copy = array.clone();
//克隆数组
int a = 0;
//分开计算位置 如果只用i 会出现重复赋值
for (int i = 0; i < copy.length; i++)
{
if (copy[i] % 2 == 1)
//奇
{
array[a++] = copy[i];
}
else
{
array[num] = copy[i];
num++;
}
}
}
public void reOrderArray3(int[] array)
{
//相对位置不变,稳定性
//插入排序的思想
int m = array.length;
int k = 0;//记录已经摆好位置的奇数的个数
for (int i = 0; i < m; i++)
{
if (array[i] % 2 == 1)
{
int j = i;
while (j > k)
{//j >= k+1
int tmp = array[j];
array[j] = array[j - 1];
array[j - 1] = tmp;
j--;
}
k++;
}
}
}
题目:
输入一个链表,输出该链表中倒数第k个结点。
思路:
方法1 遍历两遍链表,白给
方法2 建立栈,每次push一个节点,个数加一,当某个节点的next为空,push k个节点.
方法3
由于是倒数第k个,那么从最后一个节点到最后一个需要走 k-1 次
建立快慢指针,快指针先走 k-1 步,然后两个指针同时走,后一个指针的next 为空 ,前一个指针指向的节点就是目标节点.
例子:
1-2-3-4-5-6-7 求倒数第3 个,应该返回 5
快指针先走到了 3 ,那么当快指针到7,慢指针也就到了5
代码:
//栈
public ListNode FindKthToTail2(ListNode head, int k)
{
if (head == null || k == 0)
{
return null;
}
//可以先把链表反转,然后找出第k个
Stack<ListNode> stack = new Stack<ListNode>();
int count = 0;
while (head != null)
{
stack.push(head);
head = head.next;
count++;
}
if (count < k)
{
return null;
}
int i = 0;
ListNode node = null;
while (i < k)
{
node = stack.pop();
i++;
}
return node;
}
public ListNode FindKthToTail(ListNode head, int k)
{
if (head == null || k <= 0)
{
return null;
}
ListNode slow = head;
ListNode fast = head;
for (int i = 1; i < k; i++)
{
if (fast.next == null)
{
return null;
}
fast = fast.next;
}
while (fast.next != null)
{
fast = fast.next;
slow = slow.next;
}
return slow;
}