LeetCode136:一个给定的数组中,只有某一个数字是单独一个,其余数字均是两个,输出那个单独的数字
class LeetCode136{
public static void main(String[] args){
int[] arr={1,2,1,4,2}; //1 1 2 2 4
System.out.print(singleNumber(arr));
}
public static int singleNumber(int[] nums){
Arrays.sort(nums); //给这个数组排序
int i = 0 ;
while(i<nums.length){
int count = 1; //计数器设置为1
if(i==nums.length-1){ //如果下面的for循环到达最后一个数字,说明该数字就是单独的
return nums[i];
}
for(int j=i+1;j<nums.length;){
if(nums[i]==nums[j]){ //如果两个相等,count加1,然后结束本层循环
count++;
break;
}else{
return nums[i]; //如果不相等直接返回nums[i]
}
}
i += count; //记录i的变化
}
return -1;
}
/*
还有一种很简单的方法,二进制的运算求解
public int singleNumber(int[] nums) {
int result = 0;
for (int i = 0; i < nums.length; i++) { //开始数组的循环
result = result^nums[i]; //运用异或,开始的时候result就是nums[i],如果和nums[i+1]相同,直接清零,不同的话还是它本身
}
return result;
}
}
*/
思路:该题题目以经说明只有一个单独的数字,所以简单的方法就是排好序,然后从开始比较,如果相等计数器加一接着i也跟着改变,直到有不同的数字或者寻找到最后一位。
LeetCode66:
给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一。最高位数字存放在数组的首位, 数组中每个元素只存储一个数字。你可以假设除了整数 0 之外,这个整数不会以零开头。
class LeetCode66{
public static void main(String[] args){
int[] arr={1,2,9};
arr = plusOne(arr);
for(int i=0;i<arr.length;i++){
System.out.print(arr[i]);
}
}
public static int[] plusOne(int[] digits){
digits[digits.length-1] += 1; //先直接加一
for(int i=digits.length-1;i>=0;i--){
if(digits[i]<10){ //数组的最后一位也就是整数的个位,如果小于10则直接返回该数组,无需扩容
return digits;
}else{ //有进位的情况,也要扩容
digits[i] = 0; //将最后一位置为0
if(i!=0){ //只要i没有到第一位数字即整数的第一位
digits[i-1] += 1; //数组最后一位的前一位加1
}
}
}
digits = resize(digits); //如果上述的for循环中没有将数组返回说明出现了整数全为零的情况,这时候就需要扩容
return digits;
}
public static int[] resize(int[] arr){ //数组扩容
int[] newArr = new int[arr.length+1];
newArr[0] = 1;
return newArr;
}
}
思路:该题的基本原理也就是计算机运行大型数据时候的原理;我们直接用数组进行加1,开始加1的时候只要数组的最后一位小于10说明不存在进位的情况,这时候直接返回数组就可以了,如果出现了进位的情况,只要i也不是数字的第一位,我们就让前1位加1也就是i-1,当第二次循环下来后继续判断i-1位是否存在进位;如果for循环正常结束,说明需要扩容,如输入的数组为[9,9,9]。
LeetCode268:
给定一个包含 0, 1, 2, ..., n 中 n 个数的序列,找出 0 .. n 中没有出现在序列中的那个数。输入:[9,6,4,2,3,5,7,0,1] 0 1 2 3 4 5 6 7 9 输出:8
class LeetCode268{
public static void main(String[] args){
int[] arr={1,2};
System.out.print(missingNumber(arr));
}
public static int missingNumber(int[] nums) {
sort(nums);
if(nums[0]==1){ //特殊情况,如果排好序后,第一位是1说明缺少0
return 0;
}
if(nums[nums.length-1] != nums.length){ //如果最后一位不等于数组的长度说明差的那个数字就是数组长度的数字
return nums.length;
}else if(nums[0]!=0){ //如果都正常但是没有零,直接返回-1
return -1;
}
for(int i=1;i<nums.length;i++){ //遍历
if(nums[i]-nums[i-1]!=1){ //如果i位和i-1位相差不等于1,说明找打了缺少的数字
return nums[i]-1;
}
}
return -1;
}
public static void sort(int[] nums){ //插入排序
for(int i=1;i<nums.length;i++){
int j = i-1;
int e = nums[i];
while(j>=0&&nums[j]>e){
nums[j+1] = nums[j];
j--;
}
nums[j+1] = e;
}
}
}
思路:本题是查找缺少的数字,根据题意,所以最好先把特殊情况和数组输入错误的情况全部处理,接着再去查找,就直接利用,两者之差如果不等于1,说明这两个数字不是连续的。
LeetCode747:
在一个给定的数组nums中,总是存在一个最大元素。查找数组中的最大元素是否至少是数组中每个其他数字的两倍。如果是,则返回最大元素的索引,否则返回-1。
class LeetCode747{
public static void main(String[] args){
int[] arr={1};
System.out.print(dominantIndex(arr));
}
public static int dominantIndex(int[] nums){
if(nums.length == 1){ //如果长度为1直接返回-1
return -1;
}
int maxindex = maxIndex(nums); //最大值的坐标
int midmax = nums[maxindex]/2; //直接/2,方便查找
for(int i=0;i<nums.length;i++){
if(nums[i]==nums[maxindex]){ //当查找到它本身的时候结束本次循环进入下次
continue;
}
if(nums[i]>midmax){ //如果有一个数字大于它的二分之一时,直接返回-1
return -1;
}
}
return maxindex; //for循环正常结束时,返回最大元素的角标
}
public static int maxIndex(int[] nums){ //寻找最大值的坐标
int max = nums[0];
int maxindex = 0;
for(int i=1;i<nums.length;i++){
if(nums[i]>max){
max = nums[i];
maxindex = i;
}
}
return maxindex;
}
}
思路:这道题最重要的是将最大数值除以2,这样的话方便for循环的查找对比,就不用在for循环里面进行计算对比了。
LeetCode169:
给定一个大小为 n 的数组,找到其中的众数。众数是指在数组中出现次数大于 n/2 的元素。你可以假设数组是非空的,并且给定的数组总是存在众数。
class LeetCode169{
public static void main(String[] args){
int[] arr={3,2,1,1,3,3};
System.out.print(majorityElement(arr));
}
public static int majorityElement(int[] nums) {
int result = nums[0]; //开始的时候将第一个数组的值给result
int count = 1; //计数器记作1
for(int i=1;i<nums.length;i++){ //遍历
if(nums[i] == result){ //如果出现相等的数字,count+1
count++;
}else{ //如果是不同的数字
count--; //count-1
if(count == 0){ //如果count等于零时,将当前的nums[i]重新给result,count继续记作1
result = nums[i];
count = 1;
}
}
}
return result; //for循环正常结束,说明最终剩余的result就是要寻找的众数
}
}
思路:本道题是寻找众数,我们利用相消的方法做这道题。开始的时候先将数组的第一个数赋予result然后计数器置位1,开始遍历的时候从1开始,如果下一位数字和它相同直接count+1, 否则,直接将count-1,就这样循环,如果存在众数,最终会将result返回。
LeetCode905:
给定一个非负整数数组 A,返回一个数组,在该数组中,A 的所有偶数元素之后跟着所有奇数元素。你可以返回满足此条件的任何数组作为答案。
class LC905{
public static void main(String[] args){
int[] arr={1,2,3,4,5,6,7,8,9,0};
arr = sortArrayByParity(arr);
for(int i=0;i<arr.length;i++){
System.out.print(arr[i]+" ");
}
}
public static int[] sortArrayByParity(int[] A){
//“插入排序”
if(A==null){ //数组为空
return A;
}
for(int i=1;i<A.length;i++){
if(A[i]%2!=0){
continue;
}
int temp = A[i]; //将A[i]的值先赋给temp
int j=i; //定义j
for(;j>0&&A[j-1]%2!=0;j--){ //如果j没有越界且上一位是奇数,然后将前一位“覆盖”目前的数字
A[j] = A[j-1];
}
A[j] = temp; //交换
}
return A;
}
//O(n)
/*int L = 0; //设置双指针
int R = A.length-1;
while(L<R){
if(A[L]%2==0){ //如果是偶数,直接L+1向后移动
L++;
}else if(A[L]%2!=0&&A[R]%2==0){ //如果当前是奇数且最后一位是偶数就可以交换了
A[L] = A[L]+A[R];
A[R] = A[L]-A[R];
A[L] = A[L]-A[R];
L++; //交换后指针移动
R--;
}else if(A[L]%2!=0&&A[R]%2!=0){ //如果当前是奇数,最后一位是奇数,R-1直接左移
R--;
}else{ //否则右移
L++;
}
}
return A;
}*/
}
思路:本道题可以用两种思路进行解决,第一种就是利用插入排序的思路进行交换,这样会保证奇偶数字之间的相对顺序,第二种方法就是利用“双指针”,一个从数组的第一位开始,一个从数组的最后一位开始,然后两者进行判断,如果左边是奇数最右边又是偶数,这样直接交换,其余情况的话移动“指针“的位置在while循环中继续判断和比较,当左边指针大于等于右边指针的话循环结束,最终返回数组A。