Java面试编程题

1. 有一个数组,按偶奇降序排序后,按照偶奇的形式交替输出,例如{2, 4, 3, 6, 1, 5, 7, 8, 9},则输出结果为{8, 9, 7, 4, 5, 2, 3, 1}
解题思路:

先按照最简单的办法:先把数组分成奇偶两个数组,再对这两个数组进行降序排序,最后再交替输出。

代码:
public class Test1 {

    public static void main(String[] args) {

        int[] arr = { 2, 4, 6, 1, 5, 7, 8, 9 };
        System.out.println(evenOddSort(arr));
    }

    public static String evenOddSort(int[] nums) {

        int length = nums.length;

        List<Integer> evenList = new ArrayList<Integer>();
        List<Integer> oddList = new ArrayList<Integer>();

        for (int i = 0; i < length; i++) {
            int num = nums[i];
            if (num % 2 == 0) {
                evenList.add(num);
            } else {
                oddList.add(num);
            }
        }
        
        // 降序排序
        sortDesc(evenList);
        sortDesc(oddList);
        
        // 公共的次数
        int time = evenList.size() > oddList.size() ? evenList.size() : oddList.size();
        List<Integer> list = new ArrayList<Integer>();
        
        for (int i = 0; i < time; i++) {
            list.add(evenList.get(i));
            list.add(oddList.get(i));
        }
        
        // 剩余的次数
        if (evenList.size() > oddList.size()) {
            for (int i = time; i < evenList.size(); i++) {
                list.add(evenList.get(i));
            }
        }else {
            for (int i = time; i < oddList.size(); i++) {
                list.add(oddList.get(i));
            }
        }
        
        return list.toString();
    }

    public static void sortDesc(List<Integer> list) {

        for (int i = 0; i < list.size(); i++) {
            for (int j = 0; j < list.size() - i - 1; j++) {
                int current = list.get(j);
                int next = list.get(j + 1);
                if (current < next) {
                    list.set(j + 1, current);
                    list.set(j, next);
                }
            }
        }
        System.out.println(list);
    }
}

虽然解决了这个问题,但是代码很复杂,在室友的启发下,有了一种新的思路:先把列表进行降序排序,然后再用两个索引(或者叫指针),分别代表下一个偶数位置和奇数位置,使用List<Integer>来存储要输出的数组,这样在每次遍历只需要分别放入一个偶数和奇数即可。

代码:
public class Test1pro {

    public static void main(String[] args) {

        int[] arr = { 2, 4, 6, 1, 5, 7, 8, 9 };
        System.out.println(evenOddSort(arr));
    }

    public static String evenOddSort(int[] nums) {

        int length = nums.length;

        // 降序排序
        for (int i = 0; i < length; i++) {
            for (int j = 0; j < length - i - 1; j++) {
                if (nums[j] < nums[j + 1]) {
                    int temp = nums[j];
                    nums[j] = nums[j + 1];
                    nums[j + 1] = temp;
                }
            }
        }
        
        System.out.println(Arrays.toString(nums));
        
        int even = 0, odd = 0;
        List<Integer> list = new ArrayList<Integer>();
        
        for (int i = 0; i < length; i++) {
            
            // 用两个索引表示偶奇数的位置
            // 下一个偶数
            while (even < length && nums[even] % 2 != 0) {
                even ++;
            }
            if (even < length) {
                list.add(nums[even]);
                even ++;
            }
            
            // 下一个奇数
            while (odd < length && nums[odd] % 2 == 0) {
                odd ++;
            }
            if (odd < length) {
                list.add(nums[odd]);
                odd ++;
            }
        }
        return list.toString();
    }
}

2. 有一个数组,求输出能够组成的最大数,例如{20, 13, 9, 6},则输出结果为962013
解题思路:

针对给出的示例数组,按照正常的思维,那么只需要取出每个首位比较大小即可。但是如果存在首位相同的情况,那么就需要继续判断;例如{20, 211},解决办法就是设较小数的长度为x,那么只需要取两个数的前x位比较大小即可;但是如果两个数的前x位大小也一样呢?比如{20, 201},那么我们还要把较大数截掉前x位后剩下的数的首位和前x位的数的首位进行比较。可能听起来很拗口,我举个例子:
例如数组{20, 201},较小数为20,长度为2,这两个数的前2位都是20,则较大数201截掉前前2位后还剩下一个1,那么这个12小,所以组成的数是20201,但是如果是{20, 205},那么剩下的5就要比2大,则组成的数应该是20520

代码:
public class Test2 {

    public static void main(String[] args) {
        
        // [13, 6, 9]
        // [21, 2, 1]
        // [20, 1, 205]
        // [9, 7, 979, 997, 799]  9 997 979 799 7
        int[] nums = {9, 7, 979, 997, 799};
        System.out.println(maxNum(nums));
    }
    
    public static String maxNum(int[] nums) {
        
        for (int i = 0; i < nums.length; i++) {
            for (int j = i + 1; j < nums.length; j++) {
                compare(i, j, nums);
            }
        }
        
        StringBuffer buffer = new StringBuffer();
        for (int num : nums) {
            buffer.append(num);
        }
        return buffer.toString();
    }
    
    public static void compare(int i, int j, int[] nums) {
                
        int current = nums[i];
        int next = nums[j];
        System.out.println(current + " " + next + "数组:" + Arrays.toString(nums));
        int clength = String.valueOf(current).length();
        int nlength = String.valueOf(next).length();
        
        if (clength != nlength) {
            // 最短长度
            int min = clength < nlength ? clength : nlength;
            // 把两个数转成字符串
            String cstr = String.valueOf(current);
            String nstr = String.valueOf(next);
            
            // 按照最短长度进行裁剪
            // 并转化为整型进行大小比较
            int minCurrent = Integer.parseInt(cstr.substring(0, min));
            int minNext = Integer.parseInt(nstr.substring(0, min));
            if (minCurrent == minNext) {
                // 代表前面公共部分是相同的
                // 但是并不代表数长的肯定比数短的小
                // 还需要进一步判断
                // 比如【21, 2】和【20, 205】
                
                // 取出相同部分的首位
                int first = Integer.parseInt(cstr.substring(0, 1));
                if (clength > nlength) {
                    // 剩余的部分的首位
                    int last = Integer.parseInt(cstr.substring(min, min + 1));
                    // 如果剩余的部分的首位比相同部分的首位小
                    // 则需要对调两个数
                    if (last < first) {
                        nums[i] = next;
                        nums[j] = current;
                    }
                } else {
                    // 多余的部分
                    int last = Integer.parseInt(nstr.substring(min, min + 1));
                    // 如果剩余的部分的首位比相同部分的首位大
                    // 则需要对调两个数
                    if (last > first) {
                        nums[i] = next;
                        nums[j] = current;
                    }
                }
            } else {
                // 虽然长度不一样
                // 但是只需要比较相同的长度的数的大小即可
                if (minCurrent < minNext) {
                    nums[i] = next;
                    nums[j] = current;
                }
            }
        } else {
            // 代表两个数长度一样
            // 那么只需要比较两个数的大小即可
            if (current < next) {
                nums[i] = next;
                nums[j] = current;
            }
        }
    }

}

后续可能还会更新~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342