一道关于排序的面试题

以前群里有个同事发了道面试题:

两个已排好序数组,A和B,现要求对他们重新联合排序,合以的小数放入A数组中,大的数放入B中。

这题的关键是两个数组已经排好序,如果按传统的方法,进行排序当然没问题,但就没有充分利用现有的条件。

或许你可以想到插入排序,这样就可以利用a数组已排好序的优势对其进行排序了。但传统的插入排序确没有考虑到B数组也已排好序,我试过用插入序序的方式解决这个问题,但在连写了两个if,else之后,我放弃了。(我最讨厌写if,else,而且我也意识到插入排序不能很好地利用现有条件)。除了插入排序之外,我脑海中已出了几种算了,但所想到的所有算法中都要涉及数组移位问题(而且还要写if,else)。有没有人种算法,只要交换两个数组中数据就可以了呢?

如果将a中的所有元素与b中的无素进行比较,且如果a[i]>b[i],就将a[i]与b[i]互换位置,这样a[0],中的元素将是两个数组中最小的元素,而b[b.length-1]将是两个集合中最大的元素。接着我们们从两个数组中去除掉a[0]与b[b.length-1],再重复上面的操作。(这里是假设两个数组的长度是一样的)

@Override
public void sort(Integer[] arrayA, Integer[] arrayB) {
    int tmp;
    for(int j =0; j<arrayA.length;j++){

        for(int i=0;i<arrayA.length-j;i++){
            if(arrayB[i]<arrayA[i+j]){
                tmp = arrayA[i+j];
                arrayA[i+j] = arrayB[i];
                arrayB[i] = tmp;
            }

        }

    }

}

这是我所有想到解决这个问题算法中,代码量最少的一种方法了。但比较次数,以及数据交换次数不见得最少。

如果数组长度为n,那个整个比较及数据交换次数为(n+1)n/2,

下面一种方案,是利用插入排序的思想,对数组进行排序:

这种排序的思想直接来源插入排序,步骤是将a数组中的最后一个元素(也就是最大的元素)取出,插入到B数组中,并将B数组的元素向后移,将B数组的第一个元素取出,插入到A数组合适的位置,并将数组的元素前移。

当你真正去写一段代码时,才发现没那么复杂,没必要写那么多令人头皮发麻的if-else,

public class InsertArraySort implements TwoArraySortStrategy {
    @Override
    public void sort(Integer[] arrayA, Integer[] arrayB) {
            int cur ;
            while (arrayB[0] < (cur  = arrayA[arrayA.length-1])){
                insert2A(arrayA,arrayB[0]);
                insert2B(arrayB, cur);
            }
    }

    private void insert2B(Integer[] arrayB, int cur) {
        int i;
        for(i=1; i<arrayB.length && arrayB[i] <= cur
                ; i++){
            arrayB[i-1] = arrayB[i];
        }
        arrayB[i-1] = cur;
    }

    private void insert2A(Integer[] array,Integer number){

        int i;
        for(i=array.length-2; i >= 0
                && array[i] >= number
                ; i--){
            array[i+1] = array[i];
        }
        array[i+1] = number;
    }
}

我写的第一种排序算法,应该有点类似于冒泡排序。显然利用插入排序的思想在很多场合效率更高,而且后一一种可改善的地方有很多,比如可以利用二分查找法,来快速定位要插入数据的位置。然后进行移位插作。

(待继)

很早就有了要写些东西的打算,但脑袋里面稀奇古怪的思想太多,不知道从什么地方落笔好,而且我容易走神。很难在写东西时集中注意力。

时间: 2024-08-01 15:38:20

一道关于排序的面试题的相关文章

一道简单的 Java 笔试题,但值得很多人反思

面试别人,对我来说是一件新奇事,以前都是别人面试我.我清楚地知道,我在的地域与公司,难以吸引到中国的一流软件人才.所以,我特地调低了期望,很少问什么深入的技术问题,只问一些广泛的.基础的.我只要最终给Leader一句“这个人技术还行/很好/非常好”,就行了.至于其它能力.综合水平,由别人把关.为此,在挑选唯一的一道笔试题时,我特别地上心. 首先,我不敢用网上那些广为流传的,比如Leetcode.<程序员面试宝典>里的题——这些都太难了!正儿八经做,其实很少有人能在1小时内完美做出来,除非之前遇

那晚征服的一道js经典的面试题

今天朋友共享了一道js中经典的面试题,需求是这样的 给定你任意一个字符串,让你写出一个算法,求算出该字符串中出现次数最多的一个字符,并将其结果输出 刚拿到这道题的第一感觉便是定义一个count计时器,然后通过for循环 里面嵌套if判断,但是这样的话貌似并不是一个很好的解决方案 因为你并不知道该字符串是数字还是字母和 特殊符号,又或者是这三者的组合形式,所以,这种方案就显得极其的麻烦和繁琐了 所以有一个算是比较好的解决方案,代码如下 //判断一个随意字符串中出现次数最多的字母,并判断出出现过几次

一道Realtek的C笔试题

上周五参加Realtek的笔试题,有一道选择题,大概是这样的: const char a1[] = "abc"; const char a2[] = "abc"; const char *p1 = "abc"; const char *p2 = "abc"; A.a1和a2一样,p1和p2不一样: B.a1和a2不一样,p1和p2一样: C.a1和a2不一样,p1和p2也不一样: D.a1和a2一样,p1和p2一样: 我在VS

c# 字符串排序 (面试题)

将一些字符串,如: "bc", "ad", "ac", "hello", "xman", "little", "during","day" 排序的结果:“ad”,"ac",“bc”,“during”,“day”,“hello”,“little”,“xman” 采用框架自带的排序函数来调用自定义的Compare方法实现,代码段如下

排序的笔试题

1.一个从大到小的数组,按从小到大的顺序排序,哪种排序方法最快?(最坏情况) (1)冒泡排序:1+2+...n-1=O(n^2); (2)快速排序:每次partion都需要比较k-1次,才能将“第一个”数字移动到“末端”.需要进行n-1次partion才能完成排序.所以最坏情况下比较次数仍然是1+2+..+n-1=O(n^2). (3)插入排序: (4)堆排序: 补充:平均情况下,这几种排序算法的比较: (1)快速排序:平均时间复杂度为O(nlogn):最坏时间复杂度O(N^2):快速排序需要一

算法——查找排序相关面试题和leetcode使用

1.给两个字符串s和t,判断t是否为s的重新排列后组成的单词. s = "anagram", t = "nagaram", return true. s = "rat", t = "car", return false. leetcode地址:https://leetcode.com/problems/valid-anagram/description/ (1)解法一:排序,O(n*logn) class Solution:

一道简单的HashMap面试题所想到的...

前言 看到一个JDK1.7和JDK1.8中关于HashMap的一个面试题: JDK1.7和1.8中HashMap中链表的插入的方式有什么不同? 原以为自己对HashMap的源码理解的还算可以了,应该足够应付面试了.但是看到这个问题自己确实也是懵逼了一下. 查了下资料,答案是JDK1.7是插入到首部,1.8改为了尾部. 既然有改变那么就想知道是为什么了,原因其实很简答,JDK1.7中经常面试会问 并发下put 为何会导致死循环? 其实这个死循环到了JDK1.8 就不会出现了,仅仅是因为 put的后

深拷贝与浅拷贝,还有一道比较好的面试题

转自如下: https://blog.csdn.net/zzwdkxx/article/details/53409803 ================================================== 1. 深拷贝和浅拷贝(拷贝构造函数的使用) 有时候需要自己定义拷贝构造函数,以避免浅拷贝问题. 在什么情况下需要用户自己定义拷贝构造函数: 一般情况下,当类中成员有指针变量.类中有动态内存分配时常常需要用户自己定义拷贝构造函数. 在什么情况下系统会调用拷贝构造函数:(三种情况

一道简单的IOS面试题-b

题目: (参考:陈曦 包子的iOS开发)我在code review的时候,发现了某个viewController中有这样一段代码,觉得很不妥当,请尝试找出代码中的任何问题,或者可以优化的部分. -(int)searchMaxNumber:(NSArray *)numbers { int maxNumber; [numbers enumerateObjectsUsingBlock:^(NSNumber* _Nonnull obj, NSUInteger idx, BOOL * _Nonnull s