1. 程式人生 > >劍指offer面試題之把陣列排成最小的數

劍指offer面試題之把陣列排成最小的數

1,問題:輸入一個正整數陣列,把數組裡所有數字拼接起來排成一個數,列印能拼接出的所有數字中最小的一個。例如輸入陣列{3,32,321},則打印出這三個數字能排成的最小數字為321323。

2,想法:

(1),最直接的做法是求出這個陣列數字的全排列,然後把每個排列拼起來,求最後最小的值,這種情況需要考慮n!中情況,不好!

(2),另外需要考慮的一個問題是大數問題,因為單個數字不會超過數字表示範圍,但排起來後可能會超出數字表示範圍,所以最好的辦法是用字串來表示拍起來的數,而最小的數,表示成相應的字串也是最小的,因為字串的比較也是按位比較的。

所以我們要做的就是先把整數陣列轉換成一個字串陣列,然後再把字串陣列按升序排序,這樣最後排序完的字串陣列排列起來就是一個最小的數的字串表示。

3,在vs2008上的程式碼為:

#include "stdafx.h"
#include <stdlib.h>
#include <string.h>
#include <vector>
#include <iostream>
using namespace std;

const int maxnumberlength = 10;
char* strcombine1 = new char[2*maxnumberlength + 1];//兩個字串合併
char* strcombine2 = new char[2*maxnumberlength + 1];
int cmp(const void *str1, const void *str2)
{
	strcpy(strcombine1, *(char **)str1);//還必須這麼寫,不能直接寫(char*) str1;
	strcat(strcombine1, *(char **)str2);
	strcpy(strcombine2, *(char **)str2);
	strcat(strcombine2, *(char **)str1);
	return strcmp(strcombine1, strcombine2);
}
void PrintMinNumber(vector<int> numbers) 
{
	if (numbers.empty())
	{
		return;
	}
	int length = numbers.size();
	char** strnumbers = new char*[length];
	//把整形陣列存為另一個字串陣列
	for (int i = 0; i < length; i++)
	{
		strnumbers[i] = new char[maxnumberlength + 1];
		sprintf(strnumbers[i], "%d", numbers[i]);
	}
	//接下來就是排序了
	qsort(strnumbers, length, sizeof(char*), cmp);
	for (int i = 0; i < length; i++)
	{
		cout << strnumbers[i];//321323
	}
	cout << endl;
	for (int i = 0; i < length; i++)
	{
		delete[] strnumbers[i];
	}
	delete[] strnumbers;
}
int _tmain(int argc, _TCHAR* argv[])
{
	vector<int> vec(3);
	vec[0] = 3;
	vec[1] = 32;
	vec[2] = 321;
	PrintMinNumber(vec);
	system("pause");
	return 0;
}
在牛客網上的編碼為:
class Solution {
public:
    static int cmp(string s1, string s2)//用static宣告是因為它要被下邊的sort函式呼叫
    {                     //而類裡邊非靜態函式的呼叫需要具體的物件,而static函式屬於類本身
        string S1 = s1 + s2; //可以直接呼叫
        string S2 = s2 + s1;
        //return strcmp(S1, S2);//strcmp引數是字元指標
        return S1 < S2;//字串可以直接比較,這是代表升序
    }
    string PrintMinNumber(vector<int> numbers) {
        string s;
        if (numbers.empty())
        {
            return s;
        }
        vector<string> str;
        string temp;
        //把number陣列轉換成字串陣列放在str中
        int length = numbers.size();
        for (int i = 0; i < length; i++)
        {
            stringstream ss;
            ss << numbers[i];
            ss >> temp;
            str.push_back(temp);
            ss.clear();
        }
        //接下來就是對字串陣列進行排序了
        sort(str.begin(), str.end(), cmp);
        for (int i = 0; i < length; i++)
        {
            s += str[i];
        }
        return s;
    }
};

在牛客網上編碼儘量不要在類裡邊使用static變數,因為不好初始化,static成員變數,必須要在類外定義,麻煩!

儘量使用庫函式和stl容器。
非要用,就把這些變數定義成全域性變數。

//全域性變數宣告
const int maxnumberlength = 10;
char* strcombine1 = new char[2*maxnumberlength + 1];//兩個字串合併
char* strcombine2 = new char[2*maxnumberlength + 1];
class Solution {
public:
    static int cmp(const void *str1, const void *str2)
    {
	strcpy(strcombine1, *(char **)str1);//還必須這麼寫,不能直接寫(char*) str1;
	strcat(strcombine1, *(char **)str2);
	strcpy(strcombine2, *(char **)str2);
	strcat(strcombine2, *(char **)str1);
	return strcmp(strcombine1, strcombine2);
    }
    string PrintMinNumber(vector<int> numbers) {
    string s;
	if (numbers.empty())
	{
		return s;
	}
	int length = numbers.size();
	char** strnumbers = new char*[length];
	//把整形陣列存為另一個字串陣列
	for (int i = 0; i < length; i++)
	{
		strnumbers[i] = new char[maxnumberlength + 1];
		sprintf(strnumbers[i], "%d", numbers[i]);
	}
	//接下來就是排序了
	qsort(strnumbers, length, sizeof(char*), cmp);
	for (int i = 0; i < length; i++)
	{
		s += strnumbers[i];//必須用string加char*後才能繼續加char*
	}
	cout << endl;
	for (int i = 0; i < length; i++)
	{
		delete[] strnumbers[i];
	}
	delete[] strnumbers;
    return s;
    }
};


相關推薦

offer試題陣列排成小的數

1,問題:輸入一個正整數陣列,把數組裡所有數字拼接起來排成一個數,列印能拼接出的所有數字中最小的一個。例如輸入陣列{3,32,321},則打印出這三個數字能排成的最小數字為321323。 2,想法:

Offer:試題33——陣列排成小的數(java實現)(未完待續)

問題描述: 輸入一個正整數陣列,把數組裡所有數字拼接起來排成一個數,列印能拼接出的所有數字中最小的一個。例如輸入陣列{3,32,321},則打印出這三個數字能排成的最小數字為321323。

offer】Q33:陣列排成小的數

分析: 假如給定的陣列中的元素是1-9之間的數,我們怎麼來處理呢?比如[ 1,4,7,9,3,8],很簡單,排個序,就是134789。 這裡不同的一點就是,給定的數稍微複雜一點,不再單純的是1位的數,[3,32,321] 這種情況也會出現。我們還想用排序,那麼就需要自己制定

offer - 試題33 - 數組排成小的數

print offer include .html str 把數組排成最小的數 pri tr1 class #include<iostream> #include<vector> #include<string> #include<

offer試題三 :陣列中重複的數字( google 面試)

目錄 參考部落格: 題目一:找出陣列中重複的數字 思路一 思路二 題目二:不修改陣列找出重複的數字 測試: 牛客:  牛客高贊(和思路二類似都是hash對映,網友思路真是腦洞大開,這裡相關溢位問題考慮的只有~(1<<31)>>1,

Java offer 試題3:陣列中的重複數字

題目一:找出陣列中的重複數字 在一個長度為n的數組裡所有數字都在0~n-1的範圍內,陣列中某些數字是重複的,但不知道有幾個數字重複,也不知道有幾個數字重複幾次,請找出任意一個重複的數字。例如:輸入長度為7的數字組{2,3,1,0,2,5,3},對應的輸出是2或3 解法一: 對陣列進行排序

Offer:試題14——調整陣列順序使奇數位於偶數前面(java實現)

問題描述 輸入一個整數陣列,實現一個函式來調整該陣列中數字的順序,使得所有奇數位於陣列的前半部分,所有偶數位於陣列的後半部分。 思路: 1.最簡單的想法,不考慮時間複雜度,掃描陣列,

offer-8- Python實現旋轉陣列小數

一、題目描述 二、解法 def minNumberInRotateArray(rotateArray): # write code here p1 = 0 p2 = len(rotateArray)-1 mid = p1

Offer試題33:陣列排成小的數 Java 實現,三種方法

題目:把陣列排成最小的數    輸入一個正整數陣列,把數組裡所有數字拼接起來排成一個數,列印能拼接出的所有數字中最小的一個。例如輸入陣列{3,32,321},則打印出這3個數字能排成的最小數字321323. 演算法分析: 1.最直接的辦法就是先求出這個陣列中所有數字

leetcode 287. 尋找重複數【Medium】【陣列】 && Offer 試題3 題目2:不修改陣列找出重複的數字

       這道題leetcode和劍指Offer題目略有不同。leetcode說陣列中的重複數可能不止一個,但是結果要求返回一個就行;劍指Offer上說只有一個重複的數,但是重複的次數不一定。兩個題目的共性就是隻需要返回一個重複的數即可。 leetco

leetcode 240. 搜尋二維矩陣 II【陣列】【Medium】&&Offer試題4:二維陣列中的查詢

題目: 編寫一個高效的演算法來搜尋 m x n 矩陣 matrix 中的一個目標值 target。該矩陣具有以下特性: 每行的元素從左到右升序排列。 每列的元素從上到下升序排列。 示例: 現有矩陣 matrix 如下: [

Offer試題3 二維陣列中的查詢

題目描述:在一個二維陣列中(每個一維陣列的長度相同),每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成一個函式,輸入這樣的一個二維陣列和一個整數,判斷陣列中是否含有該整數。   1 2 8 9

offer{試題31:連續子陣列大和}

思路: public class test31 { public int findMaxSum(int[] arr) { if(arr.length==0) return 0; int cur = arr[0];

Offer.試題3.陣列中重複的數字

在一個長度為n的數組裡的所有數字都在0到n-1的範圍內。 陣列中某些數字是重複的,但不知道有幾個數字是重複的。也不知道每個數字重複幾次。請找出陣列中任意一個重複的數字。 例如,如果輸入長度為7的陣列{2,3,1,0,2,5,3},那麼對應的輸出是第一個重複的數字

offer試題四:二維陣列中的查詢

  題目描述 思路一:遍歷整個二維陣列 思路二:利用該二維陣列的特性(時間複雜度為O(n),因為每次比較都會去掉一行或一列) 思路三:二分法   題目描述 在一個二維陣列中(每個一維陣列的長度相同),每一行都按照從左到右遞增的順序排序,每一

offer{試題4附加:有兩個排序的陣列A1和A2 }

//思路:如出一轍,開闢新記憶體,進行比較 如果有一方為空了,另一方整體加入 public class test04_1 { public static int fun(int[] a,int[] b,int len1,int len2) {

offer{試題8:旋轉陣列小數字}

思路:還是設定兩個指標,一頭一尾,隨時變動指標,左半部分大指標往中間去,右半部分大指標前移, public class test08 { /** * 把一個數組最開始的若干個元素搬到陣列的末尾, 我們稱之陣列的旋轉。 * 輸入一個遞增

Offer試題3 二維陣列中的查詢

題目描述:在一個二維陣列中(每個一維陣列的長度相同),每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成一個函式,輸入這樣的一個二維陣列和一個整數,判斷陣列中是否含有該整數。 1 2 8 9 2 4 9

offer-試題3-二維陣列中的查詢

演算法過程: 1.選取陣列中右上角的數字 2.如果該數字小於target,則刪除這個數字所在的行row++ 3.如果該數字大於target,則刪除這個數字所在的列column-- public class Find { public

Offer試題40(Java版):陣列出現一次的數字

題目:一個整型數組裡除了兩個數字之外,其他的數字都出現了兩次。 * 請些程式找出這兩個只出現一次的數字。要求時間複雜度為O(n),空間複雜度為O(1) 例如輸入陣列{2,4,3,6,3,2,5,5},