劍指offer面試題4:替換空格和合並兩個有序數組

題目:請實現一個函數,把字符串中的每個空格替換成20%。例如:輸入“We are happy.” 輸出“We20%are20%happy


看完題目會想到,原來一個空格字符,替換後變成‘2’、‘0’、‘%’三個字符,意味着字符串變長。

有兩種解決方案:

一:創建新的字符串並在新的字符串上做替換,我們可以分配足夠多的內存。

二:在原來的字符串上做替換,那麼就有可能覆蓋修改在該字符串後面的內存。


這裏我們在原來的字符串上做替換,並且保證輸入的字符串後面有足夠多的空餘內存。

一般比較直觀的做法是從頭開始掃描字符串,每一次碰到空格字符時做替換。由於是將一個字符替換成三個字符,必須將空格後的字符向後移兩個字節,防止被覆蓋。


而按照這種做法,每替換一次空格都要從頭遍歷一次,並且移動後面的字符,顯然這種方法是不合適、效率很低。

假設字符串的長度是n,對每個空格字符,需要移動後面O(n)個字符,因此對含有O(n)個空格字符而言總的時間效率是O(n^2)


這樣我們就需要尋求高效的做法。我們可以先遍歷一遍一次字符串,統計出空格字符個數,並由此計算出替換後字符串的總長度。然後從字符串的後面開始複製和替換。


經分析,所有的字符都只複製一次,因此這個算法的時間效率是O(n)。

具體實現代碼:

void ReplaceBlank(char string[], int length)
{
	if (NULL == string || length <= 0)
	{
		return;
	}

	int stringlen = 0;
	int Blank = 0;
	int i = 0;
	while (string[i] != '\0')
	{
		if (string[i] == ' ')
			Blank++;
		i++;
	}
	//記錄原始字符串長度
	stringlen = i;
	int NewLength = stringlen + Blank * 2;

	if (NewLength > length)
		return;

	while (stringlen >= 0 && NewLength > stringlen)
	{
		if (string[stringlen] == ' ')
		{
			string[NewLength--] = '%';
			string[NewLength--] = '0';
			string[NewLength--] = '2';
		}
		else
		{
			string[NewLength--] = string[stringlen];
		}
		stringlen--;
	}
}

相關類型:

有兩個排序的數組A1,A2 內存在A1末尾有足夠多的空餘空間容納A2。實現一個函數,把A2的所有數字插入到A1中並且所有的數字是排序的。

思路很簡單,從尾到頭比較A1和A2中的數字,並把較大的數字複製到A1合適的位置。

實現代碼:

//合併兩個有序數組
#include<stdio.h>
#include<stdlib.h>

int* MergeArray(int* arr1, int* arr2,int length1,int length2)
{
	if (NULL == arr1 || NULL == arr2 )
		return 0;

	int Len = length1 + length2 - 1;
	length1--;
	length2--;
	while (length1 >= 0 && length2 >= 0)
	{
		if (arr1[length1] < arr2[length2])
		{
			arr1[Len--] = arr2[length2--];
			//length2--;
		}
		else
		{
			arr1[Len--] = arr1[length1--];
		}
		
	}
	if (length1 >= 0)
	{
		while (length1>=0)
		{
			arr1[Len] = arr1[length1--];
			Len--;
		}
	}
	else if (length2 >= 0)
	{
		while (length2>=0)
		{
			arr1[Len] = arr2[length2--];
			Len--;
		}
	}
	return arr1;
}

void display(int arr[],int num)
{
	for (int i = 0; i < num; i++)
	{
		printf("%d ", arr[i]);
	}
}

int main()
{
	int Arr1[20] = {3, 5, 7, 9, 11, 15 };
	int Arr2[7] = { 2, 4, 6, 8, 10, 13, 16 };

	MergeArray(&Arr1, &Arr2, 6, 7);
	display(Arr1, sizeof(Arr1) / sizeof(Arr1[0]));
	system("pause");
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章