数组插入问题<剑指offer>

本文探讨了如何将两个已排序数组合并成一个有序数组的方法。通过从后向前比较两个数组中的元素,可以有效地避免重复移动操作,实现高效排序。文章详细介绍了使用Java实现这一过程的步骤,并分享了在开发过程中遇到的问题及解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

*最近在做剑指offer,因为书上都是用c/c++实现的,我又看不懂c++,只能努力试试看用java来实现。*
题目:
有两个已经排好序的数组(假定它们是从小到大排序)A1和A2,请实现一个函数,把A2中的所有数字插入到A1中,并且所有的数字都是排序的。
思路:
因为两个数组都是排好序的,如果我们从前面逐个比较,后面的数字就要不断往后移动,且会重复移动,很明显,这样时间复杂度很大,那么我们从后面往前面比较只要动比较的那个数就好了,前面已经排好序了,就不需要比较了。
1.把数组1的长度扩容到两个数组长度之和。
2.从后往前,比较两个数组,并把大的往扩容后的数组里放(也是从后往前放)。

这是我第一次写的
import java.util.Arrays;
public class InsertArray {
    /*
 * 需求:有两个排序的数组a1和a2,请实现一个函数,把a2中的所有数字插入到a1中,并且所有的数字是排序的。
     * */
    public void insertSort(int[] arr1,int [] arr2){
        if(arr1!=null && arr2!=null){
            int i=arr1.length-1;                             //记录原数组1的最后一个元素的下表
            int newLength=arr1.length+arr2.length;           
            arr1=Arrays.copyOf(arr1, newLength);            //将数组1扩展为长度为两个数组之和。
            int j=arr2.length-1;                             //记录数组2最后一个元素的下标
            int k=arr1.length-1;                            //记录新数组最后一个元素下标。
            while(j>=0){                //因为是插入数组2,所以数组2没有遍历完,就要一直循环。
                if(arr2[j]>arr1[i]){       //如果数组1元素大于数组2元素,就把数组2元素存放到新数组1里去。
                    arr1[k--]=arr2[j--];
                }else if(arr2[j]==arr1[i]){             
                    arr1[k--]=arr2[j--];
                    arr1[k--]=arr1[i--];
                }else{
                    arr1[k--]=arr1[i--];
                }
            }
            return arr1;
        }else
            throw new RuntimeException("传入的数组有误");
    }
}
这是测试代码
public class InsertArrayTest {
    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int[] arr1={1,2,4,8,19,25};
        int[] arr2={3,6,7,12,19,35};
        InsertArray iArray=new InsertArray();
        iArray.insertSort(arr1, arr2);
        for(int x:arr1){
            System.out.print(x+",");
        }
    }

}

测试结果
这里写图片描述
很遗憾,结果是错的。
我先用myeclipse调试,发觉最后arr1的id在函数执行完之后又回到原来的id,为什么呢?数组作为值传递应该是引用传递,函数内的修改,应该会反馈到函数外。
后来,我想可能copyOf方法的问题,
当我查阅api,原来copyOf是复制了一个新的数组!数组长度是不可变的,我对这句话有了更深的理解,所有的数组扩容都是创立一个新的数组,这里也不例外
我用copyOf创建的新数组虽然把地址赋给了arr1,但是在函数结束后,这个新数组也会消失,arr1重新指向原来的数组。

这是修改后的代码
public class InsertArray {
    /*
     * 需求:有两个排序的数组a1和a2,请实现一个函数,把a2中的所有数字插入到a1中,并且所有的数字是排序的。
     * */
    public int[] insertSort(int[] arr1,int [] arr2){
        if(arr1!=null && arr2!=null){
            int i=arr1.length-1;                        //记录原数组1的最后一个元素的下表
            int newLength=arr1.length+arr2.length;           
            arr1=Arrays.copyOf(arr1, newLength);    //将数组1扩展为长度为两个数组之和。
            int j=arr2.length-1;                 //记录数组2最后一个元素的下标
            int k=arr1.length-1;                //记录新数组最后一个元素下标。
            while(j>=0){                        //因为是插入数组2,所以数组2没有遍历完,就要一直循环。
                if(arr2[j]>arr1[i]){           //如果数组1元素大于数组2元素,就把数组2元素存放到新数组1里去。
                    arr1[k--]=arr2[j--];
                }else if(arr2[j]==arr1[i]){             
                    arr1[k--]=arr2[j--];
                    arr1[k--]=arr1[i--];
                }else{
                    arr1[k--]=arr1[i--];
                }
            }
            return arr1;
        }else
            throw new RuntimeException("传入的数组有误");
    }
}
这里我把新创立的数组作为返回值往外传了。这样就可以了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值