字节面试题:不大于n的最大的数

特此记录一下上次面试被问没写出来的这道题

题目描述:

给定一个数组A,利用A中的数字组合形成小于n的最大数,且A中的数字可以重复使用 例如 :

  1. A = [6,8] n = 100 那么得到的数字是88
  2. n = 23121; A = {2,4,9}求由A中元素组成的、小于n的最大数,如小于23121的最大数为22999

代码解答

import java.util.*;

public class TestN {
    //题目是小于n的最大数所以不能等于n,如果要等于n,那么去掉这个getMax的部分即可
    //check是用来判断长度是否能和n一样的,这里minValue就是nums[0]
    static boolean check(String str, int minValue) {
        char c = str.charAt(0);
        if (minValue < c - '0') {
            return true;
        } else if (minValue == c - '0') {
            // 该位置相同,则递归往下查找
            return check(str.substring(1), minValue);
        } else {
            return false;
        }
    }
    
    //得到用nums中的数字能够拼出的数字的上限
    static int getMax(int[] nums, int n) {
        // 把n转成字符串,方便后面操作
        String s = String.valueOf(n);
        if (check(s, nums[0])) {
            // 长度可以和n一样
            return n - 1;
        } else {
            // 如果位数小1的话,那就直接都取nums数组中最大的那个元素拼接就行,只要位数-1
            return (int) Math.pow(10, s.length() - 1) - 1;
        }
    }

    // 二分查找,找到 <= target 的最大索引
    public static int binarySearch(int[] nums, int target) {
        int l = 0, r = nums.length - 1;
        while (l <= r) {
            int mid = (l + r) / 2;
            if (nums[mid] <= target) l = mid + 1;
            else r = mid - 1;
        }
        return r; // r 是 <= target 的最大索引
    }

    // 返回 nums 中比 str[u] 小的最大索引
    public static int getIndex(int[] nums, String str, int u) {
        int cur = str.charAt(u) - '0';
        int index = binarySearch(nums, cur);
        // 如果当前位不能取 cur,选更小的
        while (index >= 0 && nums[index] > cur) index--;
        return index;
    }

    public static String getMaxBelowN(int[] nums, int n) {
        Arrays.sort(nums);
        int maxValue = getMax(nums,n);
        String s = String.valueOf(maxValue);
        StringBuilder res = new StringBuilder();
        boolean flag = false;

        for (int i = 0; i < s.length(); i++) {
            int index = getIndex(nums, s, i);
            if (index == -1) {  // 如果无法选择当前位,就回退
                while (res.length() > 0) {
                    int lastIndex = res.length() - 1;
                    int lastDigit = res.charAt(lastIndex) - '0';

                    int newIndex = binarySearch(nums, lastDigit) - 1;
                    if (newIndex >= 0) {
                        res.setCharAt(lastIndex, (char) ('0' + nums[newIndex]));
                        break;
                    }
                    res.deleteCharAt(lastIndex);
                }

                // 全部删除,返回最大可选数
                if (res.length() == 0) {
                    char[] maxNum = new char[s.length() - 1];
                    Arrays.fill(maxNum, (char) ('0' + nums[nums.length - 1]));
                    return new String(maxNum);
                }

                while (res.length() < s.length()) {
                    res.append(nums[nums.length - 1]);
                }

                return res.toString();
            }

            res.append(nums[index]);
            if (nums[index] < s.charAt(i) - '0') flag = true;
        }

        return res.toString();
    }

    public static void main(String[] args) {
        int[] nums;
        int n;

        nums = new int[]{1, 2, 4, 6, 8};
        n = 2411;
        System.out.println(getMaxBelowN(nums, n));  // 2288
        nums = new int[]{2, 4, 6, 8};
        n = 2411;
        System.out.println(getMaxBelowN(nums, n));  // 2288
        nums = new int[]{9, 8, 7, 6};
        n = 2411;
        System.out.println(getMaxBelowN(nums, n));  // 999
        nums = new int[]{8, 7, 6};
        n = 2411;
        System.out.println(getMaxBelowN(nums, n));  // 888
        nums = new int[]{4, 5, 6};
        n = 23;
        System.out.println(getMaxBelowN(nums, n));  // 6
    }
}

#牛客激励计划#
全部评论
if (flag) { while (res.length() < s.length()) { res.append(nums[nums.length - 1]); } return res.toString(); }
1 回复 分享
发布于 2025-05-25 21:50 上海
数组A中元素数量最多为9吧,为啥还要二分查找?
点赞 回复 分享
发布于 2025-02-24 10:29 广东

相关推荐

百度日常实习面试经验分享&nbsp;|&nbsp;智能云数据平台部📋&nbsp;面试概览岗位:日常实习部门:百度智能云&nbsp;-&nbsp;数据平台部流程:一面&nbsp;→&nbsp;二面&nbsp;→&nbsp;HR通知(一天内完成)结果:✅&nbsp;通过体验&nbsp;:面试官很nice,流程高效🎤&nbsp;一面(约60分钟)项目深挖(约40分钟)简历上的项目问得很细,每个点都会追问:原理是什么?有没有考虑过其他方案?为什么选这个方案?💡&nbsp;建议:对自己的项目要非常熟悉,每个技术选型都要有理由。八股文CSS相关display:none&nbsp;vs&nbsp;visibility:hidden标准盒模型&nbsp;vs&nbsp;怪异盒模型什么是&nbsp;BFC两栏布局的实现JavaScript基础基本数据类型&nbsp;&amp;&nbsp;引用类型ES6&nbsp;引入的新类型Map&nbsp;vs&nbsp;Set&nbsp;的区别Map&nbsp;vs&nbsp;Object&nbsp;的区别Symbol&nbsp;的作用⚠️&nbsp;踩坑记录:Map和Set的区别我说成了&quot;允许重复&quot;,面试官追问是什么重复,我发现说错了赶紧改口。大家要注意:Map是键值对,键唯一;Set是值集合,值唯一。React相关用过的Hooks有哪些useRef&nbsp;的作用useMemo&nbsp;的使用场景Hooks&nbsp;的作用useContext&nbsp;的作用工程化模块化规范及区别CommonJS&nbsp;vs&nbsp;ES&nbsp;ModuleAI相关问题实习中如何使用AI?提到了&nbsp;Skills&nbsp;和平时使用的技能个人网站搭建的&nbsp;Agent&nbsp;项目大概讲了搭建流程反问环节问了团队技术栈、实习生培养机制等。🎤&nbsp;二面紧张到忘记录音了,只能回忆一些碎片项目深挖依旧是项目拷打面试官超级好,还给我的项目提了一些改进建议!八股文type&nbsp;vs&nbsp;interfaceES模块相关问题React&nbsp;什么时候不用&nbsp;useCallback/useMemoAI深度问题用AI做了些什么Agent&nbsp;Function&nbsp;Calling&nbsp;的作用开放题:Agent更需要MCP还是Skills?灵魂反问因为感觉八股回答得不太好,所以问了:&quot;我的简历和面试有什么需要改进的?&quot;结果面试官反问我:&quot;你觉得在当下的时代,基础更重要还是对AI的把握?&quot;面试官的反馈&quot;你的简历可能不太好,但是能力很不错,要是你能来公司会给你回答你刚刚的问题。&quot;✅&nbsp;面试结果很快就收到了HR的电话通知:通过了!整体来讲:✅&nbsp;流程很快✅&nbsp;过程体验很好✅&nbsp;虽然是日常实习但感觉很好🏢&nbsp;关于部门百度智能云&nbsp;-&nbsp;数据平台部有了解的uu可以说一下这个部门怎么样嘛~
拒绝pua的可乐很想...:接好运
查看25道真题和解析
点赞 评论 收藏
分享
评论
7
36
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务