首页 > 试题广场 >

给定正整数N和集合K,求不大于N的、每一位数字都在K中的最大

[问答题]
给定正整数N和集合K,求不大于N的、每一位数字都在K中的最大值M,比如N=297 K={2, 5, 8},则返回288

将N各位写进数组b[],按由高位到低位依次放入,并记录位数count,设置一个初始为0的sum值用来表示求得的值。

两个for循环,外层为b[],内层为集合数组a[],b下标由小到大循环,a下标由大到小循环,同时采用一个boolean值flag标记高位的情况,初始flag为false,如题目所示297,集合2 5 8,进入外层循环,为2,首先判断flag是否为真,若是,则按a最后一位取值计算sum,为假,进入内层循环,a中都不小于2,此时给予标记flag为真,之后几位全部按a数组最高位取。

package com.TestLittleDemo;


import java.util.Arrays;


public class Max1 {

    private static int[] a = {2,5,8};

    private static int n = 2970;


    public static void main(String[] args) {

        System.out.println(fun(a, n));

    }


    public static int fun(int[] a,int n){

        int b[] = new int[200];//数组b

        int n2= n;//n的复制,因为之后计算位数n会改变

        int num=199;

        int count = 1;//位数,最低是1

        int sum = 0;

        boolean f = false;

        while(n/10!=0){//计算位数,同时,按由高到低,从左到右依次放入b中,

            b[num]=n%10;

            n=n/10;

            count++;

            num--;

        }

        b[num]=n;

        Arrays.sort(a);

        //以b为基础进行for循环

        for (int i = num; i < 200; i++) {

            //首先判断f是否为真,是真的,就说明之前的一位a小于b,类似297,28X,十位8小于9,那么第三位就直接按a的最大取

            if(f){

                sum += (int) (a[a.length-1]*Math.pow(10,count-1));

            }else{

                for (int j = a.length-1; j >= 0; j--) {

                    //这里内层for循环采用由高到低进行循环,寻找比b小的最大数

                    if(a[j]>b[i]){

                        continue;

                    }else{

                        sum += (int) (a[j]*Math.pow(10,count-1));

                        break;

                    }

                }

            }

            //每次if else执行完,都count-1,使位数-1

            count--;

            //首先若sum=0,则说明外层for循环第一次得到结果是a集合中所有的值都比b的最高位大,所以sum的位数比b小一位,剩下的位数直接去最大

            if(sum==0){

                f=true;

            }

            //这里判断sum此时的前几位是否比b小,比如sum=2800,b=2977,都除以100,28<29,令f为真,之后的一位按最大取

            if((sum/(int)(Math.pow(10,count)))<(n2/(int)(Math.pow(10,count)))){

                f=true;

            }

        }

        return sum;

    }

}

编辑于 2018-08-01 14:49:26 回复(0)
要考虑N极小的情况。先找到的不匹配位小于K[0]时,需要之前匹配位取小一点的值,故用栈来记录M的各位。
def maxNum(N, K):
    K.sort()
    stack=[]
    AllinK=True
    length = len(str(N))
    if N<K[0]:
        print("result is None!")
        return 0
    for i in range(length):
        cur = int(str(N)[i])
        if cur in K:
            stack.append(cur)
            continue
        else:
            AllinK=False
            break
    if not AllinK:
        if cur<K[0]:
            if len(stack)>0:
                while(K[0]==stack[-1]):
                    stack.pop()
                    if len(stack)==0:
                        break
        else:
            stack.append(cur)
        if len(stack)>0:
            close=stack.pop()
            j=0
            while(K[j] < close):
                closeK=K[j] 
                if j<len(K)-1:
                    j+=1
                else:
                    break
            stack.append(closeK)
            for j in range(length-len(stack)):
                stack.append(K[-1])
        else:
            for j in range(length-1):
                stack.append(K[-1])
    result=0
    for i in range(len(stack)):
        result=result*10+stack[i]
    return result
N=2520
K=[2,5,8]
M=maxNum(N, K)
print(M)
发表于 2022-08-29 22:51:28 回复(0)

比较蠢,总之先排序,排完按位从大到小比较,如果等于,这个位就找到了,如果小于就把低位的设置为最大值。
import java.util.*;
public class Main {
public int[] bubbleSort(int[] array) {
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length - i - 1; j++) {
if (array[j + 1] < array[j]) {
int temp = array[j + 1];
array[j + 1] = array[j];
array[j] = temp;
}
}
}
return array;
}
public int max(int n, int[] array) {
ArrayList<integer> res = new ArrayList<>();
int turn = 0;
array = bubbleSort(array);
while (n != 0) {
int num = n % 10;
for (int i = array.length - 1; i >= 0; i--) {
if (array[i] == num) {
res.add(turn, array[i]);
break;
} else if (array[i] < num) {
res.add(turn, array[i]);
for (int index = turn - 1; index >= 0; index--) {
res.set(index, array[array.length - 1]);
}
break;
}
}
n = n / 10;
turn++;
}
int max = 0;
for (int i=0;i<turn;i++) {
max += res.remove(0) * Math.pow(10, i);
}
return max;
}</integer>

public static void main(String[] args) {
    System.out.println(new Main().max(297, new int[]{2, 5, 8}));
}

}

发表于 2019-07-28 17:38:36 回复(0)
def maxNum(N, K):
    length = len(str(N)) # 确定位数
    for i in range(length):
        first = int(str(N)[0])
        for j in range(first+1)[::-1]: # 确定首位最大数字
            if j in K:
                maxFirst = j
    behind = str(max(K))*(length-1)    # 确定其他位置最大数字
    maxNum = int(str(maxFirst)+behind) # 合并
    return maxNum
print maxNum(N, K)

发表于 2018-08-02 11:00:31 回复(0)
public class Test(){
     public static void main ( String[] args){

}

}

发表于 2018-08-01 09:48:36 回复(0)