记一道字节面试题:小于n的最大数

nums = [5,6,8,7]
target = 500
nums.sort()
target = str(target)
def search(nums, target):
    low, high = 0, len(nums) - 1 
    while low < high:
        mid = low + (high - low + 1) // 2
        if nums[mid] <= target:
            low = mid
        else:
            high = mid - 1
    return nums[low] if nums[low] <= target else -1
def getMaxNumbers(nums, target):
    res, ans, flag = [], 0, False
    for i in range(len(target)):
        if flag:
            res.append(nums[-1])
            continue
        subtarget = target[i]
        temp = search(nums, int(subtarget))
        if temp == -1:
            if i == 0:
                if len(target) == 1:
                    return 0
                else:
                    return str(nums[-1]) * (len(target) - 1)
            else:
                index = i - 1
                while temp == -1 and index >= 0:
                    temp = search(nums, int(target[index]) - 1)
                    index -= 1
                if temp == -1:
                    return str(nums[-1]) * (len(target) - 1)
                res[index + 1] = temp
                for j in range(index + 2, i):
                    res[j] = nums[-1]
                res.append(nums[-1])
                flag = True
        else:
            if temp == int(subtarget):
                res.append(temp)
            else:
                res.append(temp)
                flag = True
    for i in range(len(res)):
        ans = ans * 10 + res[i]
    return ans
print(getMaxNumbers(nums, target))

问题描述:给一个数组nums=[5,4,8,2],给一个n=5416, 让你从nums中选出一些元素,使得组成的数字是小于n的最大数,比如这个例子应该返回5288,当时没想出来,让面试官换了一道题,事后顺着一些大佬的思路写了下,感觉贪心加二分这个思路比较接近正确答案,有没有人看下这个方法行不行
 

#字节跳动#
全部评论
void maxNumber(const vector<int> &v, int num) { vector<int> arr, ans; int minChoose=10, maxChoose=0; bool exist[10]; for(int x:v) { exist[x]= true; minChoose = min(minChoose, x); //可选择的最小值 maxChoose = max(maxChoose, x); //可选择的最大值 } while(num) //将num每一位存到数组 { arr.push_back(num%10); num /= 10; } reverse(arr.begin(), arr.end()); //答案应尽可能和num位数相同,若位数相同无解,则答案减少一位且每位取最大值,如100 {2,3,4}的答案为44 for(int i=0;i<arr.size>= minChoose ? arr[i] : arr[i] - 1); while (j >= 0 && !exist[j]) j--; if(j<0) //同位数无解,退而求次降低解的位数 { ans.clear(); for (int k = 0; k < arr.size() - 1; ++k) ans.push_back(maxChoose); break; } else if(j!=arr[i]) //当前位取了小于原数同位的值,则解确定,后面每一位都可以取最大值 { ans.push_back(j); while (ans.size()</arr.size></int></int>
1 回复 分享
发布于 2022-05-03 16:16
实际上 数只有十个 那我们贪心就好了 我们首先匹配这个数 如果每一位都在这个数组中存在 就修改最小的一位 如果不 就把最高的不能匹配的位之后变成数组中最大值 这一位找一个小的数代替
5 回复 分享
发布于 2022-05-02 00:28
代码考虑不周全,好几次跑出来的值和taget相等
1 回复 分享
发布于 2022-05-26 00:05
我也是贪心➕二分的解法,前两天我朋友问我的,一会我贴上来,不保证没有漏洞,但是目前的用例是都过了
1 回复 分享
发布于 2022-05-02 10:28
这个代码有点问题呀,没有考虑到最后如果全部都是匹配成等于的情况,例如nums = [2], target = 22的情况。
点赞 回复 分享
发布于 2024-10-13 14:54 福建
数位dp?
点赞 回复 分享
发布于 2024-08-28 23:18 浙江
有人知道这道题的oj链接吗,想测试下
点赞 回复 分享
发布于 2022-08-08 21:54
你这个5416咋输出888,我尝试了一下
点赞 回复 分享
发布于 2022-07-23 17:12
题目规模不大,2**31 也就 10 个数字,dfs+剪枝方法 虽然不是最优不过也可以过给的用例
点赞 回复 分享
发布于 2022-05-25 17:00
今天我也问的这道题,和他说的是贪心+二分,然后面试官说应该就是最优的
点赞 回复 分享
发布于 2022-05-06 15:58
重新编辑了下,有几个边界情况考虑错了
点赞 回复 分享
发布于 2022-05-02 16:34
我擦,长的
点赞 回复 分享
发布于 2022-05-02 00:15

相关推荐

import&nbsp;java.util.*;class&nbsp;Node&nbsp;{public&nbsp;Integer&nbsp;key;public&nbsp;Integer&nbsp;value;public&nbsp;Long&nbsp;timeStamp;public&nbsp;Node(Integer&nbsp;key,&nbsp;Integer&nbsp;value,&nbsp;Long&nbsp;timeStamp)&nbsp;{this.key&nbsp;=&nbsp;key;this.value&nbsp;=&nbsp;value;this.timeStamp&nbsp;=&nbsp;timeStamp;}}class&nbsp;LRUCache&nbsp;{private&nbsp;Map&lt;Integer,&nbsp;Node&gt;&nbsp;map;private&nbsp;int&nbsp;capacity;public&nbsp;LRUCache(int&nbsp;capacity)&nbsp;{map&nbsp;=&nbsp;new&nbsp;LinkedHashMap&lt;&gt;();this.capacity&nbsp;=&nbsp;capacity;}public&nbsp;int&nbsp;get(int&nbsp;key)&nbsp;{Node&nbsp;node&nbsp;=&nbsp;map.get(key);//&nbsp;key&nbsp;不存在if&nbsp;(node&nbsp;==&nbsp;null)&nbsp;{return&nbsp;-1;}//&nbsp;key&nbsp;过期(懒删除策略)if&nbsp;(isExpire(node))&nbsp;{map.remove(key);return&nbsp;-1;}map.remove(key);map.put(key,&nbsp;node);return&nbsp;node.value;}public&nbsp;void&nbsp;put(int&nbsp;key,&nbsp;int&nbsp;value,&nbsp;Long&nbsp;timeStamp)&nbsp;{Node&nbsp;node&nbsp;=&nbsp;map.get(key);if&nbsp;(node&nbsp;==&nbsp;null)&nbsp;{&nbsp;&nbsp;//&nbsp;key&nbsp;不存在node&nbsp;=&nbsp;new&nbsp;Node(key,&nbsp;value,&nbsp;timeStamp);if&nbsp;(map.size()&nbsp;&lt;&nbsp;capacity)&nbsp;{&nbsp;&nbsp;//&nbsp;有额外空间map.put(key,&nbsp;node);}&nbsp;else&nbsp;{&nbsp;&nbsp;//&nbsp;没有额外空间//&nbsp;先尝试移除过期keyremoveExpireNodes();//&nbsp;如果空间还是不足,移除最老的keyif&nbsp;(map.size()&nbsp;&gt;=&nbsp;capacity)&nbsp;{map.remove(map.keySet().iterator().next());}map.put(key,&nbsp;node);}}&nbsp;else&nbsp;{&nbsp;&nbsp;//&nbsp;key&nbsp;存在map.remove(key);node&nbsp;=&nbsp;new&nbsp;Node(key,&nbsp;value,&nbsp;timeStamp);map.put(key,&nbsp;node);}}private&nbsp;void&nbsp;removeExpireNodes()&nbsp;{for&nbsp;(Node&nbsp;node&nbsp;:&nbsp;map.values())&nbsp;{if&nbsp;(isExpire(node))&nbsp;{map.remove(node.key);}}}private&nbsp;boolean&nbsp;isExpire(Node&nbsp;node)&nbsp;{if&nbsp;(node.timeStamp&nbsp;==&nbsp;null)&nbsp;{&nbsp;&nbsp;//&nbsp;没有时间戳表示永久不过期return&nbsp;false;}return&nbsp;System.currentTimeMillis()&nbsp;&gt;&nbsp;node.timeStamp;}}class&nbsp;LRUTTL&nbsp;{public&nbsp;static&nbsp;void&nbsp;main(String[]&nbsp;args)&nbsp;{LRUCache&nbsp;cache&nbsp;=&nbsp;new&nbsp;LRUCache(2);cache.put(1,&nbsp;10,&nbsp;null);cache.put(2,&nbsp;20,&nbsp;null);System.out.println(cache.get(1));&nbsp;&nbsp;//&nbsp;10cache.put(3,&nbsp;30,&nbsp;null);System.out.println(cache.get(2));&nbsp;&nbsp;//&nbsp;-1cache.put(4,&nbsp;40,&nbsp;System.currentTimeMillis()&nbsp;+&nbsp;1000);try&nbsp;{System.out.println(cache.get(1));&nbsp;&nbsp;//&nbsp;-1Thread.sleep(1500);System.out.println(cache.get(3));&nbsp;&nbsp;//&nbsp;30System.out.println(cache.get(4));&nbsp;&nbsp;//&nbsp;-1}&nbsp;catch&nbsp;(InterruptedException&nbsp;e)&nbsp;{throw&nbsp;new&nbsp;RuntimeException(e);}}}优化点:可以维护一个map结构存储&lt;最小过期时间,节点数量&gt;来判断当前LinkedList中是否存在已经过期的node,可以一定程度地减少&nbsp;removeExpireNodes&nbsp;的调用次数
点赞 评论 收藏
分享
评论
7
66
分享

创作者周榜

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