阿里面试输在了算法题上

大家好,扬哥的一个朋友最近向扬哥哭诉:输在了阿里的最后一面的算法题上。究竟是什么难题?今天我们一起来看看,这道算法题,应该怎么解。

阿里面试输在了算法题上

题目

  • 给定一个数组 nums,将其划分为两个连续子数组 left 和 right,使得:
  • left 中的每个元素都小于或等于 right 中的每个元素。
  • left 和 right 都是非空的。
  • left 的长度要尽可能小。

示例 1:

输入:nums = [5,0,3,8,6]
输出:3
解释:left = [5,0,3],right = [8,6]

示例 2:

输入:nums = [1,1,1,0,6,12]
输出:4
解释:left = [1,1,1,0],right = [6,12]

解题步骤

算法代码

private int getSplitIdx(int[] nums){
    int pos = -1;
    int[] minBs = new int[nums.length];
    minBs[nums.length-1] = nums[nums.length-1];
    //从右到左查找,当前数值跟后面数值对比,取小的数值
    for(int i=nums.length-2; i>=0; i--){
        if(minBs[i+1]>nums[i]){
            minBs[i] = nums[i];
        }else{
            minBs[i] = minBs[i+1];
        }
    }
    printArray("过度数组:   ", minBs, true);
    //从左往右查找
    int max = nums[0];
    for(int i=1; i<minBs.length; i++){
        //如果nums[i]<max 继续往后找
        if(nums[i]<max){
            continue;
        }
        //如果过度数组大于前面所有的数据,返回下标
        if(minBs[i]>max){
            return i;
        }else{//否则更新最大值
            max = nums[i];
        }
    }
    return pos;
}

算法思路

  • 从右往左找最小值,存储在过数组中。如果数组当前值比后面的值大,则保留后面小的值为当前值,即从右往左找最小值。
  • 从左往后找最大值,初始max为数组的第一个元素,如果max小于过数据对应的值,则找到临界点,否则将数组的当前值,赋值给max。

验证代码一

@Test
public void testArraySplitByCompare(){
    System.out.println("数组拆分为left和right两部分,使左边的任意一个数字都小于右边的任意一个数字");
    int nums[] = new int[]{5,0,3,8,6};
    printArray("输入数组:   ", nums, true);
    int pos = getSplitIdx(nums);
    if(pos>-1){
        System.out.println("输出位置:   " + pos);
        printArray("具体解释:   left = ", Arrays.copyOfRange(nums, 0, pos), false);
        printArray(", right = ", Arrays.copyOfRange(nums, pos, nums.length), true);
    }else{
        System.out.println("Error ...");
    }
}

private void printArray(String preParam, int[] bs, boolean fin){
    System.out.print(preParam+Arrays.toString(bs));
    if(fin){
        System.out.println();
    }
}

输出结果一

数组拆分为left和right两部分,使左边的任意一个数字都小于右边的任意一个数字
输入数组:   [50386]
数组:   [00366]
输出位置:   3
具体解释:   left = [503], right = [86]

进程已结束,退出代码 0

将 int nums[] = new int[]{5,0,3,8,6}; 替换为  int nums[] = new int[]{1,1,1,0,6,12}

验证代码二

@Test
    public void testArraySplitByCompare(){
        System.out.println("数组拆分为left和right两部分,使左边的任意一个数字都小于右边的任意一个数字");
        int nums[] = new int[]{1,1,1,0,6,12};
        printArray("输入数组:   ", nums, true);
        int pos = getSplitIdx(nums);
        if(pos>-1){
            System.out.println("输出位置:   " + pos);
            printArray("具体解释:   left = ", Arrays.copyOfRange(nums, 0, pos), false);
            printArray(", right = ", Arrays.copyOfRange(nums, pos, nums.length), true);
        }else{
            System.out.println("Error ...");
        }
    }

输出结果二

数组拆分为left和right两部分,使左边的任意一个数字都小于右边的任意一个数字
输入数组:   [1110612]
数组:   [0000612]
输出位置:   4
具体解释:   left = [1110], right = [612]

进程已结束,退出代码 0

总结


阿里面试输在了算法题上

算法是软件开发中的灵魂,好的算法,能降低CPU的使用率,甚至在一定程度上可以减少内存的使用,提升系统的性能。这道阿里算法题,你做对了么,欢迎留言交流。

点击这里给我留言吧

原文始发于微信公众号(扬哥手记):阿里面试输在了算法题上

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/269306.html

(0)
Java朝阳的头像Java朝阳

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!