元素右移问题

元素右移的问题,一般就是两层循环的问题。一个个往后移动移动k次,这也算一种解法,比较容易思考,就是每次循环把最后一个存起来其他依次后移,循环结束把最后一个放在第一个的位置,java实现的代码如下。

public int[] moveRight(int [] arr,int moveSize){
       while(moveSize>0){
           int t = arr[arr.length - 1];
           for(int i = arr.length - 1; i > 0; i --){
               arr[i] = arr[i - 1];
           }
           arr[0] = t;
           moveSize--;
       }
       return arr;
   }

上一个算法虽然可以实现,但是交换次数太多,不如新定义一个数组,实现一步到位的移法,代码的实现如下:

public int[] moveRight(int [] arr,int moveSize){
       int[] newArr=new int[arr.length];
       for (int i=0;i<arr.length;i++){
           newArr[(i+moveSize)%arr.length]=arr[i];
       }
       return newArr;
   }

下面说下经典方法,三次倒置数组中对应位置的元素; 简单说一下原理:数组元素右移k个位置的结果是,原来在后面的k个元素跑到了数组前面,原来在前面的length-k个元素,跑到了数组的后面,并且前后两部分元素各自的顺序和移动前一致,而倒置整个数组元素就是让后面k个元素跑到前面去,让前面length-k个元素跑到后面去,但是倒置之后前后两部分元素的顺序跟移动之前不一样了,倒置了,所以要把两部分的元素倒置回来。

public static void moveArrayElement3(int[] arrayint k) {
       // 倒置所有元素
       reverse(array,0,array.length-1);
       // 倒置前k个元素
       reverse(array0, k - 1);
       // 倒置后length - k个元素
       reverse(array, k, array.length - 1);
   }

   private static void reverse(int[] arrayint begin, int end) {
       int length = end - begin + 1;
       int half = length / 2;
       for(int i = 0; i < half; i++) {
           int temp = array[begin];
           array[begin] = array[end];
           array[end] = temp;
           begin++;
           end--;
       }
   }

两个等长有序数组中位数问题

一看最简单的方法就是归并两个数组,然后找到他们的中位数,也算市一种解法,数组里面操作的方法比较常用的就是双指针(索引)。代码实现如下

public int findMid(int a[], int b[]) {
       int result[];
       //定义一个新数组,长度为两个数组长度之和
       result = new int[a.length + b.length];
       //i:a数组下标    j:b数组下标  k:新数组下标
       int i = 0, j = 0, k = 0;
       // 按位循环比较两个数组,较小元素的放入新数组,下标加一(注意,较大元素对应的下标不加一),直到某一个下标等于数组长度时退出循环
       while (i < a.length && j < b.length) {
           if (a[i] <= b[j]) {
               result[k++] = a[i++];
           } else {
               result[k++] = b[j++];
           }
       }
       /* 后面连个while循环是用来保证两个数组比较完之后剩下的一个数组里的元素能顺利传入 *
        * 此时较短数组已经全部放入新数组,较长数组还有部分剩余,最后将剩下的部分元素放入新数组,大功告成*/

       while (i < a.length) {
           result[k++] = a[i++];
       }
       while (j < b.length) {
           result[k++] = b[j++];
       }
       return result[result.length / 2];
   }

上次方法的改进,没必要全部归并啊,定义一个标记到数组长度的时候,返回这时两个索引的较小值就可以,代码如下

public int MergeList(int a[], int b[]) {
       int i=0,j=0,count=1;
       while(count<a.length){
           if(a[i]<=b[j]){
               i++;
           }else {
               j++;
           }
           count++;
       }
       return (a[i]<b[j]?a[i]:b[j]);
   }

其实这两个等长的有序数组市可以二分归并的,不过代码比较复杂,但是效率更高。感兴趣的小伙伴可以自己尝试一下。愿意的也可以一起探讨一下。

本文属于原创,如有疑问请后台留言,如有转载请标注原作者,版权归本公众号所有。如果你喜欢我写的文章请关注微信公众号 Java资源社区,欢迎大家继续关注本公众号的技术博文。如果您觉得本文章对你有所帮助的话,不妨点个赞,您的支持就是我坚持原创的动力。