Algorithm 如何从数字列表中指示最长回文?

Algorithm 如何从数字列表中指示最长回文?,algorithm,data-structures,palindrome,Algorithm,Data Structures,Palindrome,我试图解决一个问题,我们需要写一个函数,在这个函数中,给定一个数字列表,我们需要从列表中的数字中找到最长的回文 例如: 如果给定列表为:[3,47,6,6,5,6,15,22,1,6,15] 我们可以返回的最长回文是长度为9的回文,例如[6,15,6,3,47,3,6,15,6] 此外,我们还有以下限制: 只能使用数组队列、数组堆栈和链接hashmap,以及我们应该返回的列表,并且函数必须在线性时间内运行。我们只能使用恒定的附加空间 我的做法如下: 由于回文可以在具有偶数个特定字符的情况下形成,

我试图解决一个问题,我们需要写一个函数,在这个函数中,给定一个数字列表,我们需要从列表中的数字中找到最长的回文

例如:

如果给定列表为:[3,47,6,6,5,6,15,22,1,6,15]

我们可以返回的最长回文是长度为9的回文,例如[6,15,6,3,47,3,6,15,6]

此外,我们还有以下限制:

只能使用数组队列、数组堆栈和链接hashmap,以及我们应该返回的列表,并且函数必须在线性时间内运行。我们只能使用恒定的附加空间

我的做法如下:

由于回文可以在具有偶数个特定字符的情况下形成,因此我们可以迭代列表中的所有元素,并存储在链式哈希映射中,每个数字出现在列表中的次数。这应该需要O(N)个时间,因为链式散列映射中的每个查找都需要固定的时间,而遍历列表则需要线性时间

然后我们可以迭代链式散列映射中的所有数字,查看哪些数字出现偶数次,并相应地生成一个回文。在最坏的情况下,这将需要O(n)线性时间

现在我想知道两件事:

  • 我应该如何制作实际的回文?比如我如何使用被允许使用的数据结构来生成回文?我认为,由于队列是一个后进先出的数据结构,对于出现偶数次的每个数字,我们将其添加到队列中一次,添加到堆栈中一次,依此类推。最后,我们可以将队列中的所有内容从队列中取出,然后从堆栈中弹出一次,然后将其添加到列表中

  • 似乎用我的方法,我需要两次线性运行来解决这个问题。我想知道是否有更快的方法来做到这一点


  • 任何和所有的帮助都将不胜感激。谢谢

    我得到了一个解决方案,它的回文只针对数字,而不是数字。 对于输入:[51,15] 我们将返回[15]|[51],而不是[51,15]=>(5,1,1,5); 问题3不会出现两次(并且会出现在答案中),请提供更多您的示例 也许我不明白这个问题

    public static int[] polidrom(int [] numbers){
            HashMap<Integer/*the numbere*/,Integer/*how many time appeared*/> hash = new HashMap<>();
            boolean middleFree= false;
            int middleNumber = 0;
            int space = 0;
            Stack<Integer> stack = new Stack<>();
            for (Integer num:numbers) {//count how mant times each digit appears
                if(hash.containsKey(num)){hash.replace(num,1+hash.get(num));}
                else{hash.put(num,1);}
            }
            for (Integer num:hash.keySet()) {//how many times i can use pairs
                int original =hash.get(num);
                int insert = (int)Math.floor(hash.get(num)/2);
                if(hash.get(num) % 2 !=0){middleNumber = num;middleFree = true;}//as no copy
                hash.replace(num,insert);
                if(insert != 0){
                    for(int i =0; i < original;i++){
                        stack.push(num);
                    }
                }
            }
    
            space = stack.size();
            if(space == numbers.length){ space--;};//all the numbers are been used
            int [] answer = new int[space+1];//the middle dont have to have an pair
            int startPointer =0 , endPointer= space;
            while (!stack.isEmpty()){
                int num = stack.pop();
                answer[startPointer] = num;
                answer[endPointer] = num;
                startPointer++;
                endPointer--;
            }
            if (middleFree){answer[answer.length/2] = middleNumber;}
            return answer;
        }
    
    公共静态int[]polidrom(int[]数字){
    HashMap hash=新的HashMap();
    布尔值middleFree=false;
    整数=0;
    int空间=0;
    堆栈=新堆栈();
    对于(Integer num:numbers){//count每个数字的mant次数
    if(hash.containsKey(num)){hash.replace(num,1+hash.get(num));}
    else{hash.put(num,1);}
    }
    对于(Integer num:hash.keySet()){//我可以使用对多少次
    int original=hash.get(num);
    intinsert=(int)Math.floor(hash.get(num)/2);
    如果(hash.get(num)%2!=0){middleNumber=num;middleFree=true;}//作为无副本
    替换(num,insert);
    如果(插入!=0){
    对于(int i=0;i
    空间O(n)=>{stack,hashMap,answer Array}; 复杂性:O(n) 您可以跳过我使用堆栈的部分,在同一个循环中构建应答数组。 我想不出一种方法,你至少可以重复两次;
    希望我能帮上忙

    当回文只针对数字而不是数字时,我找到了一个解决方案。 对于输入:[51,15] 我们将返回[15]|[51],而不是[51,15]=>(5,1,1,5); 问题3不会出现两次(并且会出现在答案中),请提供更多您的示例 也许我不明白这个问题

    public static int[] polidrom(int [] numbers){
            HashMap<Integer/*the numbere*/,Integer/*how many time appeared*/> hash = new HashMap<>();
            boolean middleFree= false;
            int middleNumber = 0;
            int space = 0;
            Stack<Integer> stack = new Stack<>();
            for (Integer num:numbers) {//count how mant times each digit appears
                if(hash.containsKey(num)){hash.replace(num,1+hash.get(num));}
                else{hash.put(num,1);}
            }
            for (Integer num:hash.keySet()) {//how many times i can use pairs
                int original =hash.get(num);
                int insert = (int)Math.floor(hash.get(num)/2);
                if(hash.get(num) % 2 !=0){middleNumber = num;middleFree = true;}//as no copy
                hash.replace(num,insert);
                if(insert != 0){
                    for(int i =0; i < original;i++){
                        stack.push(num);
                    }
                }
            }
    
            space = stack.size();
            if(space == numbers.length){ space--;};//all the numbers are been used
            int [] answer = new int[space+1];//the middle dont have to have an pair
            int startPointer =0 , endPointer= space;
            while (!stack.isEmpty()){
                int num = stack.pop();
                answer[startPointer] = num;
                answer[endPointer] = num;
                startPointer++;
                endPointer--;
            }
            if (middleFree){answer[answer.length/2] = middleNumber;}
            return answer;
        }
    
    公共静态int[]polidrom(int[]数字){
    HashMap hash=新的HashMap();
    布尔值middleFree=false;
    整数=0;
    int空间=0;
    堆栈=新堆栈();
    对于(Integer num:numbers){//count每个数字的mant次数
    if(hash.containsKey(num)){hash.replace(num,1+hash.get(num));}
    else{hash.put(num,1);}
    }
    对于(Integer num:hash.keySet()){//我可以使用对多少次
    int original=hash.get(num);
    intinsert=(int)Math.floor(hash.get(num)/2);
    如果(hash.get(num)%2!=0){middleNumber=num;middleFree=true;}//作为无副本
    替换(num,insert);
    如果(插入!=0){
    对于(int i=0;i
    空间O(n)=>{stack,hashMap,answer Array}; 复杂性:O(n) 您可以跳过我使用堆栈的部分,在同一个循环中构建应答数组。 我想不出一种方法,你至少可以重复两次; 希望我帮了忙

    不可能