正如标题所写的一样,给定一个正整数的数组,求这些数组合起来的最大值。
eg:
arr[] = {12, 3}
输出是
312
感觉这个题目有点难度,关键是如何比较这两个数字,哪个在前哪个在后的问题,有些小极端的case在里面
头文件
#ifndef __TEST_ARR_MAXNUMBER_H_
#define __TEST_ARR_MAXNUMBER_H_
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <vector>
using namespace std;
typedef struct _Link {
int data;
struct _Link *next;
} Link;
int transform2link(int *arr, int len, Link*** pplinkarr);
void quicksort_link(Link **plinkarr, int low, int high);
bool compare_node(Link *pnode1, Link *pnode2);
int output_number(Link **plinkarr, int len);
int destory_link(Link*** pplinkarr, int len);
#endif //__TEST_ARR_MAXNUMBER_H_
cpp文件如下,关键在两个数的比较上,注释里面写了点。
#include "test_arr_maxnumber.h"
const int N = 1024;
int transform2link(int *arr, int len, Link*** pplinkarr)
{
if (arr == NULL || len <= 0 || pplinkarr == NULL)
return 0;
Link **plinkarr = *pplinkarr;
int i = 0;
int mem_arr[N];
int mem_len = 0;
int j = 0;
int key = -1;
for (i = 0; i < len; i++)
{
plinkarr[i] = NULL;
}
for (i = 0; i < len; i++)
{
int tmp = arr[i];
j = 0;
key = -1;
while (tmp > 0)
{
key = tmp % 10;
mem_arr[j++] = key;
tmp = tmp / 10;
}
mem_len = j;
Link *pnode = NULL;
Link *ptmp = NULL;
for (j = mem_len-1; j >= 0; j--)
{
key = mem_arr[j];
ptmp = new Link();
ptmp->data = key;
ptmp->next = NULL;
if (plinkarr[i] == NULL)
{
plinkarr[i] = ptmp;
pnode = ptmp;
} else {
pnode->next = ptmp;
pnode = pnode->next;
}
}
}
return 0;
}
void quicksort_link(Link **plinkarr, int low, int high)
{
if (low >= high)
return;
int i = low;
int j = high;
Link *plink;
plink = plinkarr[j];
// descend order
while (i < j)
{
while (i < j && compare_node(plinkarr[i], plink))
i++;
plinkarr[j] = plinkarr[i];
while (i < j && compare_node(plink, plinkarr[j]))
j--;
plinkarr[i] = plinkarr[j];
}
plinkarr[i] = plink;
quicksort_link(plinkarr, i+1, high);
quicksort_link(plinkarr, low, i-1);
return;
}
bool compare_node(Link *pnode1, Link *pnode2)
{
if (pnode1 == NULL)
return false;
if (pnode2 == NULL)
return true;
// case 1
// case 2
Link *ptmp1 = pnode1;
Link *ptmp2 = pnode2;
while (ptmp1 != NULL && ptmp2 != NULL)
{
if (ptmp1->data > ptmp2->data) {
return true;
} else if (ptmp1->data < ptmp2->data) {
return false;
} else if (ptmp1->data == ptmp2->data) {
ptmp1 = ptmp1->next;
ptmp2 = ptmp2->next;
}
}
if (ptmp1 == NULL && ptmp2 == NULL) {
// 这个case 比较trick, 适合一般情况,需要仔细想想
// 适合 7 与 77777777777 和 78 与 787878787878
return true;
} else if (ptmp1 == NULL && ptmp2 != NULL) {
// 这里是一个递归的算法
// 用一个循环体来判断最后的, 判断最后的结果是多少 true or false
// 循环体可能是截断的,但是跟前面一样就ok
// 78787878 与 787878, 循环体最后是 78,
// 上面两个值其实是一样的,因为循环体一样
ptmp1 = pnode1;
return compare_node(ptmp1, ptmp2);
} else if (ptmp1 != NULL && ptmp2 == NULL) {
// 同上
ptmp2 = pnode2;
return compare_node(ptmp1, ptmp2);
}
return true;
}
int output_number(Link **plinkarr, int len)
{
int i = 0;
Link *pnode = NULL;
for (i = 0; i < len; i++)
{
pnode = plinkarr[i];
while (pnode != NULL)
{
std::cout << pnode->data;
pnode = pnode->next;
}
std::cout << " ";
}
std::cout << std::endl;
return 0;
}
int destory_link(Link*** pplinkarr, int len)
{
Link** plinkarr = *pplinkarr;
Link* pnode = NULL;
Link* ptmp = NULL;
int i = 0;
for (i = 0; i < len; i++)
{
pnode = plinkarr[i];
ptmp = pnode->next;
while (pnode->next != NULL)
{
delete pnode;
pnode = ptmp;
ptmp = pnode->next;
}
delete pnode;
plinkarr[i] = NULL;
}
return 0;
}
int main(int argc, char *argv[])
{
int arr[] = {1, 31, 254, 7, 723, 78, 78789, 77, 712, 9, 5, 3, 6};
int len = sizeof(arr) / sizeof(int);
int i = 0;
for (i = 0; i < len; i++)
{
std::cout << arr[i] << " ";
}
std::cout << std::endl;
Link **plinkarr = new Link* [len];
for (i = 0; i < len; i++)
{
plinkarr[i] = NULL;
}
transform2link(arr, len, &plinkarr);
quicksort_link(plinkarr, 0, len-1);
output_number(plinkarr, len);
destory_link(&plinkarr, len);
delete [] plinkarr;
plinkarr = NULL;
return 0;
}
这个题用链表可能更加方便一点,尤其在处理循环体的时候,直接用链表来实现递归,更加方便,操作更加简单一点。这个题目只有自己写一遍才会理解当中的小技巧。
本文介绍了一种算法,该算法通过将一组正整数重新排列以形成最大的可能数值。使用链表进行数字存储,并通过快速排序及自定义比较逻辑实现最优组合。

68

被折叠的 条评论
为什么被折叠?



