1.面试题第56题
题目描述
一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
1)最初的思路:将数组中的第一个数字与其他的数字进行对比,如果有与它相同的就将第二个数字与其他数字对比,依次下去。问题:会发现时间复杂度过高。真正写代码时会根据题目的特征加一些判断,来减小比较的次数,例如将添加一个计数器,在有两个出现一次数字时就停止遍历数组,但依然不是一个好的方法。
代码实现如下(在牛客网上运行通过):
//num1,num2分别为长度为1的数组。传出参数
//将num1[0],num2[0]设置为返回结果
public class Solution {
public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
int count = 0;
boolean flag = true;
for(int i=0;i<array.length;i++)
{
flag = true;
for(int j=0;j<i;j++)
{
if(array[i]==array[j])
{
flag = false;
}
}
for(int j=i+1;flag==true&&j<array.length;j++)
{
if(array[i]==array[j])
{
flag = false;
}
}
if(flag==true)
{
count++;
if(count==1)
num1[0] = array[i];
if(count==2)
{
num2[0] = array[i];
break;
}
}
}
}
}
2)剑指offer作者给出的思路:
2.面试题第21题
题目描述
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,是的所有奇数位于数组的前半部分,所有的偶数位于数组的后半部分。
常见思路:从头扫描这个数组,每碰到一个偶数,拿出这个数字,并把位于这个数字后面的所有数字都向前挪动一位,将取出的偶数放到最后,由于每碰到一个偶数就需要移动O(n)个数字,因此总的时间复杂度是O(n^2)。
public static void reOrderArray1(int [] array)
{
int i = 0;
int count = 0;
//count防止代码继续判断已经被挪过的偶数,进入死循环
while(i<=array.length-1&&count!=array.length-i-1)
{
if(array[i]%2==0) //如果是偶数
{
int temp = array[i];
for(int k=i;k+1<=array.length-1;k++)
{
array[k] = array[k+1];
}
array[array.length-1] = temp;
count++;
}
else
{
i++;
}
}
}
更好的方法:维护两个指针:第一个指针初始化指向数组的第一个数字,它只向后移动。第二个指针初始化指向数组的最后一个数字,它只向前移动。如果第一个指针指向偶数就停止移动,同样的第二个指针指向奇数就停止移动,然后两只指针指向的数字交换。两指针重复上面的操作,直到第二个指针在第一个指针前面为止。
代码实现:
public static void reOrderArray2(int [] array)
{
int i = 0;
int j = array.length - 1;
while(i<j)
{
while(i<j&&array[i]%2==1)
{
i++;
}
while(i<j&&array[j]%2==0)
{
j--;
}
if(i>=j) //这一行代码是重点,类似与快速排序
break;
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
题目描述
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并
保证奇数和奇数,偶数和偶数之间的相对位置不变
。
思路:用两个指针考,指针i指向第一个偶数,指针j指向第一个奇数,将[i,j-1]的数都向右移动一位,将指针j指向的数据赋值给指针i指向的位置。
代码实现:
public class Solution {
public static void reOrderArray(int [] array) {
int i = 0;
int j = i+1;
while(i<=array.length-1&&j<=array.length-1)
{
while(i<=array.length-1&&array[i]%2==1)
{
i++;
}
j = i+1;
while(j<=array.length-1&&array[j]%2==0)
{
j++;
}
if(j<=array.length-1)
{
int temp = array[j];
for(int k=j;k-1>=i;k--)
{
array[k] = array[k-1];
}
array[i] = temp;
}
if(j>array.length-1) //如果发现后面的都是偶数了就退出循环
break;
i++;
}
}
}