数组中只出现一次的数字
如果数组中只有一个数字出现了一次,对数组所有数求一次异或,两个相同的数的异或是0。那么如果数组中有两个数出现了一次,其他出现了两次,将这数组分成两个子数组,这两个数字分别出现在这两个子数组中,那么就转换成了前面所说的求异或的问题。那么怎么分呢,这里的思路是根据要求的这两个数的异或之后最右边不为1的这一位进行划分的。
//num1,num2分别为长度为1的数组。传出参数
//将num1[0],num2[0]设置为返回结果
public class Solution {
public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
int res = 0;
for(int x:array)
res ^= x;
int splitBit = 1;
while((res & splitBit)==0)
splitBit = splitBit << 1;
int res1 = 0;
int res2 = 0;
for(int x:array){
if((x & splitBit) != 0)
res1 ^= x;
else
res2 ^= x;
}
num1[0] = res1;
num2[0] = res2;
}
}
和为 S 的两个数字
输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。
思路:由于是排好序的数组,因此对于和相等的两个数来说,相互之间的差别越大,那么乘积越小,因此我们使用两个指针,一个从前往后遍历,另一个从后往前遍历数组即可。
import java.util.ArrayList;
public class Solution {
public ArrayList<Integer> FindNumbersWithSum(int [] array,int sum) {
ArrayList<Integer> res = new ArrayList<Integer>();
int i=0;
int j = array.length-1;
while(i<j){
if(array[i]+array[j]>sum)
j-=1;
else if(array[i]+array[j]<sum)
i+=1;
else{
res.add(array[i]);
res.add(array[j]);
return res;
}
}
return res;
}
}