三11、連續子數組的最大和node
輸入一個整數組,數組裏有正數也有負數。數組中一個或連續的多個整數組成一個子數組。ios
求全部子數組的和的最大值。要求時間複雜度爲O(n)。數組
#include <iostream> #include <stdio.h> bool g_InvalidInput = false; int FindGreatestSumOfSubArray( int* pData, int nLength ) { if( pData == NULL || ( nLength <= 0 ) ) { g_InvalidInput = true; return 0; } g_InvalidInput = false; int nCurSum = 0; int nGreatestSum = 0x80000000; for( int i = 0; i < nLength; ++i ) { if( nCurSum <= 0 ) nCurSum = pData[ i ]; else nCurSum += pData[ i ]; if( nCurSum > nGreatestSum ) nGreatestSum = nCurSum; } return nGreatestSum; } void Test( const char* testName, int* pData, int nLength, int expected, bool expectedFlag ) { if( testName != NULL ) printf( "%s begins: \n", testName ); int result = FindGreatestSumOfSubArray( pData, nLength ); if( result == expected && expectedFlag == g_InvalidInput ) printf( "Passed.\n" ); else printf( "Failed.\n" ); } // 1, -2, 3, 10, -4, 7, 2, -5 void Test1() { int data[] = { 1, -2, 3, 10, -4, 7, 2, -5 }; Test( "Test1", data, sizeof( data ) / sizeof( int ), 18, false ); } // 全部數字都是負數 // -2, -8, -1, -5, -9 void Test2() { int data[] = { -2, -8, -1, -5, -9 }; Test( "Test2", data, sizeof( data ) / sizeof( int ), -1, false ); } // 全部數字都是正數 // 2, 8, 1, 5, 9 void Test3() { int data[] = { 2, 8, 1, 5, 9 }; Test( "Test3", data, sizeof( data ) / sizeof( int ), 25, false ); } // 無效輸入 void Test4() { Test( "Test4", NULL, 0, 0, true ); } int main() { Test1(); Test2(); Test3(); Test4(); return 0; }
輸入一個整數n,求從1到n這n個整數的十進制表示中1出現的次數。例如輸入12,從1到12測試
這些整數中包含1的數字有1, 10, 11和12, 1一共出現了5次。this
#include <iostream> #include <stdio.h> int NumberOf1( unsigned int n ) { int number = 0; while( n ) { if( n % 10 == 1 ) number++; n = n / 10; } return number; } int NumberOfBetween1AndN( unsigned int n ) { int number = 0; for( unsigned int i = 1; i <= n; ++i ) number += NumberOf1( i ); return number; } void Test( const char* testName, int n, int expected ) { if( testName != NULL ) printf( "%s begins: \n", testName ); if( NumberOfBetween1AndN( n ) == expected ) printf( "Solution passed.\n" ); else printf( "Solution failed.\n" ); printf( "\n" ); } void Test() { Test( "Test1", 1, 1 ); Test( "Test2", 5, 1 ); Test( "Test3", 10, 2 ); Test( "Test4", 55, 16 ); Test( "Test5", 99, 20 ); Test( "Test6", 10000, 4001 ); Test( "Test7", 21345, 18821 ); Test( "Test8", 0, 0 ); } int main() { Test(); return 0; }
輸入一個正整數數組,把數組全部數字拼接起來排成一個數,打印能拼接出的全部數字中最小google
的一個。例如輸入數組{ 3, 32, 321 },則打印出這3個數字能排成的最小數字321323.spa
#include <iostream> #include <stdio.h> #include <string> #include <algorithm> #include <string.h> const int g_MaxNumberLength = 10; char* g_StrCombine1 = new char[ g_MaxNumberLength * 2 + 1 ]; char* g_StrCombine2 = new char[ g_MaxNumberLength * 2 + 1 ]; int compare( const void* strNumber1, const void* strNumber2 ) { strcpy( g_StrCombine1, *( const char** )strNumber1 ); strcat( g_StrCombine1, *( const char** )strNumber2 ); strcpy( g_StrCombine2, *( const char** )strNumber2 ); strcat( g_StrCombine2, *( const char** )strNumber1 ); return strcmp( g_StrCombine1, g_StrCombine2 ); } void PrintMinNumber( int * numbers, int length ) { if( numbers == NULL || length <= 0 ) return; char** strNumbers = ( char** )( new int[ length ] ); for( int i = 0; i < length; ++i ) { strNumbers[ i ] = new char[ g_MaxNumberLength + 1 ]; sprintf( strNumbers[ i ], "%d", numbers[ i ] ); } qsort( strNumbers, length, sizeof( char* ), compare ); for( int i = 0; i < length; ++i ) printf( "%s", strNumbers[ i ] ); printf( "\n" ); for( int i = 0; i < length; ++i ) delete[] strNumbers[ i ]; delete[] strNumbers; } void Test( const char* testName, int* numbers, int length, char* expectedResult ) { if( testName != NULL ) printf( "%s begins:\n", testName ); if( expectedResult != NULL ) printf( "Expected result is: \t%s\n", expectedResult ); printf( "Actual result is: \t" ); PrintMinNumber( numbers, length ); printf( "\n" ); } void Test1() { int numbers[] = { 3, 5, 1, 4, 2 }; Test( "Test1", numbers, sizeof( numbers ) / sizeof( int ), "12345" ); } void Test2() { int numbers[] = { 3, 32, 321 }; Test( "Test2", numbers, sizeof( numbers ) / sizeof( int ), "321323" ); } void Test3() { int numbers[] = { 3, 323, 32123 }; Test( "Test3", numbers, sizeof( numbers ) / sizeof( int ), "321233233" ); } void Test4() { int numbers[] = { 1, 11, 111 }; Test( "Test4", numbers, sizeof( numbers ) / sizeof( int ), "111111" ); } // 數組中只有一個數字 void Test5() { int numbers[] = { 321 }; Test( "Test5", numbers, sizeof( numbers ) / sizeof( int ), "321" ); } void Test6() { Test( "Test6", NULL, 0, "Don't print anything." ); } int main() { Test1(); Test2(); Test3(); Test4(); Test5(); Test6(); return 0; }
咱們把只含包含因子二、3和5的數稱爲醜數(Ugly Number)。求按從小到大的順序的第指針
1500個醜數。例如六、8都是醜數,但14不是,由於它包含因子7.習慣上咱們把1當作醜數。code
#include <iostream> #include <stdio.h> bool IsUgly( int number ) { while( number % 2 == 0 ) number /= 2; while( number % 3 == 0 ) number /= 3; while( number % 5 == 0 ) number /= 5; return ( number == 1 ) ? true : false; } int GetUglyNumber_Solution1( int index ) { if( index <= 0 ) return 0; int number = 0; int uglyFound = 0; while( uglyFound < index ) { ++number; if( IsUgly( number ) ) { ++uglyFound; } } return number; } void Test( int index, int expected ) { if( GetUglyNumber_Solution1( index ) == expected ) printf( "solution1 passed\n" ); else printf( "solution1 failed\n" ); } int main() { Test( 1500, 859963392 ); return 0; }
#include <iostream> #include <stdio.h> int Min( int number1, int number2, int number3 ) { int min = ( number1 < number2 ) ? number1 : number2; min = ( min < number3 ) ? min : number3; return min; } // 獲取第k個醜數,假定1爲第一個醜數 int GetUglyNumber_Solution2( int index ) { if( index <= 0 ) return 0; // 定義醜數數組,用於記錄排序的醜數 int *pUglyNumbers = new int[ index ]; // 第一個醜數爲1 pUglyNumbers[ 0 ] = 1; // 第一個醜數的座標是0,下一個醜數的座標從1開始 int nextUglyIndex = 1; // 定義三個指向醜數數組的指針,用它們來標識從數組中的哪個數開始計算M2,M3和M5,開始都是醜數數組的首地址 int *pMultiply2 = pUglyNumbers; int *pMultiply3 = pUglyNumbers; int *pMultiply5 = pUglyNumbers; while( nextUglyIndex < index ) { // M2=*T2 * 2, M3=*T3 * 3, M5=*T5 * 5 int min = Min( *pMultiply2 * 2, *pMultiply3 * 3, *pMultiply5 * 5 ); // 求M2,M3,M5的最小值做爲新的醜數放入醜數數組 pUglyNumbers[ nextUglyIndex ] = min; // 每次生成新的醜數的時候,去更新T2,T3和T5. while( *pMultiply2 * 2 <= pUglyNumbers[ nextUglyIndex ] ) ++pMultiply2; while( *pMultiply3 * 3 <= pUglyNumbers[ nextUglyIndex ] ) ++pMultiply3; while( *pMultiply5 * 5 <= pUglyNumbers[ nextUglyIndex ] ) ++pMultiply5; ++nextUglyIndex; } // 由於醜數有序排列,因此醜數數組中的最後一個醜數就是咱們所求的第index個醜數。 int ugly = pUglyNumbers[ nextUglyIndex - 1 ]; delete[] pUglyNumbers; return ugly; } void Test( int index, int expected ) { if( GetUglyNumber_Solution2( index ) == expected ) printf( "solution2 passed\n" ); else printf( "solution2 failed\n" ); } int main() { Test( 1500, 859963392 ); return 0; }
在字符串中找出第一個只出現一次的字符。如輸入"abaccdeff",則輸出'b'。排序
#include <iostream> #include <stdio.h> #include <string> char FirstNotRepeatingChar( char* pString ) { if( pString == NULL ) return '\0'; const int tableSize = 256; unsigned int hashTable[ tableSize ]; for( unsigned int i = 1; i < tableSize; ++i ) hashTable[ i ] = 0; char* pHashKey = pString; while( *( pHashKey ) != '\0' ) hashTable[ *( pHashKey++ ) ]++; pHashKey = pString; while( *pHashKey != '\0' ) { if( hashTable[ *pHashKey ] == 1 ) return *pHashKey; pHashKey++; } return '\0'; } void Test( char* pString, char expected ) { if( FirstNotRepeatingChar( pString ) == expected ) printf( "Test passed.\n" ); else printf( "Test failed.\n" ); } int main() { // 常規輸入測試,存在只出現一次的字符 Test( "google", 'l' ); // 常規輸入測試,不存在只出現一次的字符 Test( "aabccdbd", '\0' ); // 常規輸入測試,全部字符都只出現一次 Test( "abcdefg", 'a' ); // 魯棒性測試,輸入NULL Test( NULL, '\0' ); return 0; }
三十6、數組中的逆序對
在數組中的兩個數字若是前面一個數字大於後面的數字,則這兩個數字組成一個逆序對。輸
入一個數組,求出這個數組中的逆序對的總數。
#include <iostream> #include <stdio.h> int InversePairsCore( int* data, int* copy, int start, int end ) { if( start == end ) { copy[ start ] = data[ start ]; return 0; } int length = ( end -start ) / 2; int left = InversePairsCore( copy, data, start, start + length ); int right = InversePairsCore( copy, data, start + length + 1, end ); // i初始化爲前半段最後一個數字的下標 int i = start + length; // j初始化爲後半段最後一個數字的下標 int j = end; int indexCopy = end; int count = 0; while( i >= start && j >= start + length + 1 ) { if( data[ i ] > data[ j ] ) { copy[ indexCopy-- ] = data[ i-- ]; count += j - start - length; } else { copy[ indexCopy-- ] = data[ j-- ]; } } for( ; i >= start; --i ) copy[ indexCopy-- ] = data[ i ]; for( ; j >= start + length + 1; --j ) copy[ indexCopy-- ] = data[ j ]; return left + right + count; } int InversePairs( int* data, int length ) { if( data == NULL || length < 0 ) return 0; int* copy = new int[ length ]; for( int i = 0; i < length; ++i ) copy[ i ] = data[ i ]; int count = InversePairsCore( data, copy, 0, length - 1 ); delete[] copy; return count; } void Test( const char* testName, int* data, int length, int expected ) { if( testName != NULL ) printf( "%s begins: ", testName ); if( InversePairs( data, length ) == expected ) printf( "Passed.\n" ); else printf( "Failed.\n" ); } void Test1() { int data[] = { 1, 2, 3, 4, 7, 6, 5 }; int expected = 3; Test( "Test1", data, sizeof( data ) / sizeof( int ), expected ); } // 遞減排序數組 void Test2() { int data[] = { 6, 5, 4, 3, 2, 1 }; int expected = 15; Test( "Test2", data, sizeof( data ) / sizeof( int ), expected ); } // 遞增排序數組 void Test3() { int data[] = { 1, 2, 3, 4, 5, 6 }; int expected = 0; Test( "Test3", data, sizeof( data ) / sizeof( int ), expected ); } // 數組中只有一個數字 void Test4() { int data[] = { 1 }; int expected = 0; Test( "Test4", data, sizeof( data ) / sizeof( int ), expected ); } int main() { Test1(); Test2(); Test3(); Test4(); return 0; }
輸入兩個鏈表,找出它們的第一個公共結點。
#include <iostream> #include <stdio.h> #include <stdlib.h> struct ListNode { int m_nValue; ListNode* m_pNext; }; ListNode* CreateListNode( int value ) { ListNode* pNode = new ListNode(); pNode->m_nValue = value; pNode->m_pNext = NULL; return pNode; } void ConnectListNodes( ListNode* pCurrent, ListNode* pNext ) { if( pCurrent == NULL ) { printf( "Error to connect two nodes.\n" ); exit( 1 ); } pCurrent->m_pNext = pNext; } void PrintListNode( ListNode* pNode ) { if( pNode == NULL ) { printf( "The node is NULL\n" ); } else { printf( "The key in node is %d.\n", pNode->m_nValue ); } } void PrintList( ListNode* pHead ) { printf( "PrintList start: \n" ); ListNode* pNode = pHead; while( pNode != NULL ) { printf( "%d\t", pNode->m_nValue ); pNode = pNode->m_pNext; } } void DestroyNode( ListNode* pNode ) { if( pNode != NULL ) { delete pNode; } } void DestroyList( ListNode* pHead ) { ListNode* pNode = pHead; while( pNode != NULL ) { pHead = pHead->m_pNext; delete pNode; pNode = pHead; } } unsigned int GetListLength( ListNode* pHead ) { unsigned int nLength = 0; ListNode* pNode = pHead; while( pNode != NULL ) { ++ nLength; pNode = pNode->m_pNext; } return nLength; } ListNode* FindFirstCommonNode( ListNode *pHead1, ListNode *pHead2 ) { // 獲得兩個鏈表的長度 unsigned int nLength1 = GetListLength(pHead1); unsigned int nLength2 = GetListLength(pHead2); int nLengthDif = nLength1 - nLength2; ListNode* pListHeadLong = pHead1; ListNode* pListHeadShort = pHead2; if( nLength2 > nLength1 ) { pListHeadLong = pHead2; pListHeadShort = pHead1; nLengthDif = nLength2 - nLength1; } // 先在長鏈表上走幾步,再同時在兩個鏈表上遍歷 for( int i = 0; i < nLengthDif; ++i ) pListHeadLong = pListHeadLong->m_pNext; while( ( pListHeadLong != NULL ) && ( pListHeadShort != NULL ) && ( pListHeadLong != pListHeadShort ) ) { pListHeadLong = pListHeadLong->m_pNext; pListHeadShort = pListHeadShort->m_pNext; } // 獲得第一個公共結點 ListNode* pFisrtCommonNode = pListHeadLong; return pFisrtCommonNode; } void Test( const char* testName, ListNode* pHead1, ListNode* pHead2, ListNode* pExpected ) { if( testName != NULL ) printf( "%s begins: ", testName ); ListNode* pResult = FindFirstCommonNode( pHead1, pHead2 ); if( pResult == pExpected ) printf( "Passed.\n" ); else printf( "Failed.\n" ); } // 第一個公共結點在鏈表中間 // 1 - 2 - 3 \ // 6 - 7 // 4 - 5 / void Test1() { ListNode* pNode1 = CreateListNode( 1 ); ListNode* pNode2 = CreateListNode( 2 ); ListNode* pNode3 = CreateListNode( 3 ); ListNode* pNode4 = CreateListNode( 4 ); ListNode* pNode5 = CreateListNode( 5 ); ListNode* pNode6 = CreateListNode( 6 ); ListNode* pNode7 = CreateListNode( 7 ); ConnectListNodes( pNode1, pNode2 ); ConnectListNodes( pNode2, pNode3 ); ConnectListNodes( pNode3, pNode6 ); ConnectListNodes( pNode4, pNode5 ); ConnectListNodes( pNode5, pNode6 ); ConnectListNodes( pNode6, pNode7 ); Test( "Test1", pNode1, pNode4, pNode6 ); DestroyNode( pNode1 ); DestroyNode( pNode2 ); DestroyNode( pNode3 ); DestroyNode( pNode4 ); DestroyNode( pNode5 ); DestroyNode( pNode6 ); DestroyNode( pNode7 ); } // 公共結點是第一個結點 // 1 - 2 - 3 - 4 - 5 // 兩個鏈表徹底重合 void Test2() { ListNode* pNode1 = CreateListNode( 1 ); ListNode* pNode2 = CreateListNode( 2 ); ListNode* pNode3 = CreateListNode( 3 ); ListNode* pNode4 = CreateListNode( 4 ); ListNode* pNode5 = CreateListNode( 5 ); ConnectListNodes( pNode1, pNode2 ); ConnectListNodes( pNode2, pNode3 ); ConnectListNodes( pNode3, pNode4 ); ConnectListNodes( pNode4, pNode5 ); Test( "Test2", pNode1, pNode1, pNode1 ); DestroyList( pNode1 ); } int main() { Test1(); Test2(); return 0; }
統計一個數字在排序數組中出現的次數。例如輸入排序數組{1, 2, 3, 3, 3, 3, 3, 4, 5}和數字3,
因爲3在這個數組中出現了4次,所以輸出4.
#include <iostream> #include <stdio.h> int GetFirstK( int* data, int length, int k, int start, int end ) { if( start > end ) return -1; int middleIndex = ( start + end ) / 2; int middleData = data[ middleIndex ]; if( middleData == k ) { if( ( middleIndex > 0 && data[ middleIndex - 1 ] != k ) || middleIndex == 0 ) return middleIndex; else end = middleIndex - 1; } else if( middleData > k ) end = middleIndex - 1; else start = middleIndex + 1; return GetFirstK( data, length, k, start, end ); } int GetLastK( int* data, int length, int k, int start, int end ) { if( start > end ) return -1; int middleIndex = ( start + end ) / 2; int middleData = data[ middleIndex ]; if( middleData == k ) { if( ( middleIndex < length - 1 && data[ middleIndex + 1 ] != k ) || middleIndex == length - 1 ) return middleIndex; else start = middleIndex + 1; } else if( middleData < k ) start = middleIndex + 1; else end = middleIndex - 1; return GetLastK( data, length, k, start, end ); } int GetNumberOfK( int* data, int length, int k ) { int number = 0; if( data != NULL && length > 0 ) { int first = GetFirstK( data, length, k, 0, length - 1 ); int last = GetLastK( data, length, k, 0, length - 1 ); if( first > -1 && last > -1 ) number = last - first + 1; } return number; } void Test( const char* testName, int data[], int length, int k, int expected ) { if( testName != NULL ) printf( "%s begins: ", testName ); int result = GetNumberOfK( data, length, k ); if( result == expected ) printf( "Passed.\n" ); else printf( "Failed.\n" ); } // 查找的數字出如今數組的中間 void Test1() { int data[] = { 1, 2, 3, 3, 3, 3, 4, 5 }; Test( "Test1", data, sizeof( data ) / sizeof( int ), 3, 4 ); } // 查找的數組出如今數組的開頭 void Test2() { int data[] = { 3, 3, 3, 3, 4, 5 }; Test( "Test2", data, sizeof( data ) / sizeof( int ), 3, 4 ); } // 查找的數組出如今數組的結尾 void Test3() { int data[] = { 1, 2, 3, 3, 3, 3 }; Test( "Test3", data, sizeof( data ) / sizeof( int ), 3, 4 ); } // 查找的數字不存在 void Test4() { int data[] = { 1, 3, 3, 3, 3, 4, 5 }; Test( "Test4", data, sizeof( data ) / sizeof( int ), 2, 0 ); } // 查找的數字比第一個數字還小,不存在 void Test5() { int data[] = {1, 3, 3, 3, 3, 4, 5 }; Test( "Test5", data, sizeof( data ) / sizeof( int ), 0, 0 ); } // 查找的數字比最後一個數字還大,不存在 void Test6() { int data[] = { 1, 3, 3, 3, 3, 4, 5 }; Test( "Test6", data, sizeof( data ) / sizeof( int ), 6, 0 ); } // 數組中的數字從頭至尾都是查找的數字 void Test7() { int data[] = { 3, 3, 3, 3 }; Test( "Test7", data, sizeof( data ) / sizeof( int ), 3, 4 ); } // 數組中的數字從頭至尾只有一個重複的數字,不是查找的數字 void Test8() { int data[] = { 3, 3, 3, 3 }; Test( "Test8", data, sizeof( data ) / sizeof( int ), 4, 0 ); } // 數組中只有一個數字,是查找的數字 void Test9() { int data[] = { 3 }; Test( "Test9", data, sizeof( data ) / sizeof( int ), 3, 1 ); } // 數組中只有一個數字,不是查找的數字 void Test10() { int data[] = { 3 }; Test( "Test10", data, sizeof( data ) / sizeof( int ), 4, 0 ); } // 魯棒性測試,數組空指針 void Test11() { Test( "Test11", NULL, 0, 0, 0 ); } int main() { Test1(); Test2(); Test3(); Test4(); Test5(); Test6(); Test7(); Test8(); Test9(); Test10(); Test11(); return 0; }
輸入一顆二叉樹的根結點,求該樹的深度。從根結點到葉結點依次通過的結點(含根、葉結
點)造成樹的一條路徑,最長路徑的長度爲樹的深度。
#include <iostream> #include <stdio.h> struct BinaryTreeNode { int m_nValue; BinaryTreeNode* m_pLeft; BinaryTreeNode* m_pRight; }; BinaryTreeNode* CreateBinaryTreeNode( int value ) { BinaryTreeNode* pNode = new BinaryTreeNode(); pNode->m_nValue = value; pNode->m_pLeft = NULL; pNode->m_pRight = NULL; return pNode; } void ConnectTreeNodes( BinaryTreeNode* pParent, BinaryTreeNode* pLeft, BinaryTreeNode* pRight ) { if( pParent != NULL ) { pParent->m_pLeft = pLeft; pParent->m_pRight = pRight; } } void PrintTreeNode( BinaryTreeNode* pNode ) { if( pNode != NULL ) { printf( "value of this node is: %d\n", pNode->m_nValue ); if( pNode->m_pLeft != NULL ) printf( "value of its left child is: %d.\n", pNode->m_pLeft->m_nValue ); else printf( "left child is null.\n" ); if( pNode->m_pRight != NULL ) printf( "value of its right child is: %d.\n", pNode->m_pRight->m_nValue ); else printf( "right child is null.\n" ); } else { printf( "this node is null.\n" ); } printf( "\n" ); } void PrintTree( BinaryTreeNode* pRoot ) { PrintTreeNode( pRoot ); if( pRoot != NULL ) { if( pRoot->m_pLeft != NULL ) PrintTree( pRoot->m_pLeft ); if( pRoot->m_pRight != NULL ) PrintTree( pRoot->m_pRight ); } } void DestroyTree( BinaryTreeNode* pRoot ) { if( pRoot != NULL ) { BinaryTreeNode* pLeft = pRoot->m_pLeft; BinaryTreeNode* pRight = pRoot->m_pRight; delete pRoot; pRoot = NULL; DestroyTree( pLeft ); DestroyTree( pRight ); } } int TreeDepth( BinaryTreeNode* pRoot ) { if( pRoot == NULL ) return 0; int nLeft = TreeDepth( pRoot->m_pLeft ); int nRight = TreeDepth( pRoot->m_pRight ); return ( nLeft > nRight ) ? ( nLeft + 1 ) : ( nRight + 1 ); } void Test( BinaryTreeNode* pRoot, int expected ) { int result = TreeDepth( pRoot ); if( expected == result ) printf( "Test passed.\n" ); else printf( "Test failed.\n" ); } // 1 // / \ // 2 3 // /\ \ // 4 5 6 // / // 7 void Test1() { printf( "Test1 begins.\n" ); BinaryTreeNode* pNode1 = CreateBinaryTreeNode( 1 ); BinaryTreeNode* pNode2 = CreateBinaryTreeNode( 2 ); BinaryTreeNode* pNode3 = CreateBinaryTreeNode( 3 ); BinaryTreeNode* pNode4 = CreateBinaryTreeNode( 4 ); BinaryTreeNode* pNode5 = CreateBinaryTreeNode( 5 ); BinaryTreeNode* pNode6 = CreateBinaryTreeNode( 6 ); BinaryTreeNode* pNode7 = CreateBinaryTreeNode( 7 ); ConnectTreeNodes( pNode1, pNode2, pNode3 ); ConnectTreeNodes( pNode2, pNode4, pNode5 ); ConnectTreeNodes( pNode3, NULL, pNode6 ); ConnectTreeNodes( pNode5, pNode7, NULL ); Test( pNode1, 4 ); DestroyTree( pNode1 ); } // 1 // / // 2 // / // 3 // / // 4 // / // 5 void Test2() { printf( "Test2 begins.\n" ); BinaryTreeNode* pNode1 = CreateBinaryTreeNode( 1 ); BinaryTreeNode* pNode2 = CreateBinaryTreeNode( 2 ); BinaryTreeNode* pNode3 = CreateBinaryTreeNode( 3 ); BinaryTreeNode* pNode4 = CreateBinaryTreeNode( 4 ); BinaryTreeNode* pNode5 = CreateBinaryTreeNode( 5 ); ConnectTreeNodes( pNode1, pNode2, NULL ); ConnectTreeNodes( pNode2, pNode3, NULL ); ConnectTreeNodes( pNode3, pNode4, NULL ); ConnectTreeNodes( pNode4, pNode5, NULL ); Test( pNode1, 5 ); DestroyTree( pNode1 ); } // 樹中只有1個結點 void Test3() { printf( "Test3 begins.\n" ); BinaryTreeNode* pNode1 = CreateBinaryTreeNode( 1 ); Test( pNode1, 1 ); DestroyTree( pNode1 ); } // 樹中沒有結點 void Test4() { printf( "Test4 begins.\n" ); Test( NULL, 0 ); } int main() { Test1(); Test2(); Test3(); Test4(); return 0; }
輸入一顆二叉樹的根結點,判斷該樹是否是平衡二叉樹。若是某二叉樹中任意結點的左右子
樹的深度相差不超過1,那麼它就是一顆平衡二叉樹。
#include <iostream> #include <stdio.h> struct BinaryTreeNode { int m_nValue; BinaryTreeNode* m_pLeft; BinaryTreeNode* m_pRight; }; BinaryTreeNode* CreateBinaryTreeNode( int value ) { BinaryTreeNode* pNode = new BinaryTreeNode(); pNode->m_nValue = value; pNode->m_pLeft = NULL; pNode->m_pRight = NULL; return pNode; } void ConnectTreeNodes( BinaryTreeNode* pParent, BinaryTreeNode* pLeft, BinaryTreeNode* pRight ) { if( pParent != NULL ) { pParent->m_pLeft = pLeft; pParent->m_pRight = pRight; } } void PrintTreeNode( BinaryTreeNode* pNode ) { if( pNode != NULL ) { printf( "value of this node is: %d\n", pNode->m_nValue ); if( pNode->m_pLeft != NULL ) printf( "value of its left child is: %d.\n", pNode->m_pLeft->m_nValue ); else printf( "left child is null.\n" ); if( pNode->m_pRight != NULL ) printf( "value of its right child is: %d.\n", pNode->m_pRight->m_nValue ); else printf( "right child is null.\n" ); } else { printf( "this node is null.\n" ); } printf( "\n" ); } void PrintTree( BinaryTreeNode* pRoot ) { PrintTreeNode( pRoot ); if( pRoot != NULL ) { if( pRoot->m_pLeft != NULL ) PrintTree( pRoot->m_pLeft ); if( pRoot->m_pRight != NULL ) PrintTree( pRoot->m_pRight ); } } void DestroyTree( BinaryTreeNode* pRoot ) { if( pRoot != NULL ) { BinaryTreeNode* pLeft = pRoot->m_pLeft; BinaryTreeNode* pRight = pRoot->m_pRight; delete pRoot; pRoot = NULL; DestroyTree( pLeft ); DestroyTree( pRight ); } } int TreeDepth( BinaryTreeNode* pRoot ) { if( pRoot == NULL ) return 0; int nLeft = TreeDepth( pRoot->m_pLeft ); int nRight = TreeDepth( pRoot->m_pRight ); return ( nLeft > nRight ) ? ( nLeft + 1 ) : ( nRight + 1 ); } bool IsBalanced_Solution( BinaryTreeNode* pRoot ) { if( pRoot == NULL ) return true; int left = TreeDepth( pRoot->m_pLeft ); int right = TreeDepth( pRoot->m_pRight ); int diff = left - right; if( diff > 1 || diff < -1 ) return false; return IsBalanced_Solution( pRoot->m_pLeft ) && IsBalanced_Solution( pRoot->m_pRight ); } void Test( const char* testName, BinaryTreeNode* pRoot, bool expected ) { if( testName != NULL ) printf( "%s begins:\n", testName ); printf( "Solution begins: " ); if( IsBalanced_Solution( pRoot ) == expected ) printf( "Passed.\n" ); else printf( "Failed.\n" ); } // 徹底二叉樹 // 1 // / \ // 2 3 // /\ / \ // 4 5 6 7 void Test1() { BinaryTreeNode* pNode1 = CreateBinaryTreeNode( 1 ); BinaryTreeNode* pNode2 = CreateBinaryTreeNode( 2 ); BinaryTreeNode* pNode3 = CreateBinaryTreeNode( 3 ); BinaryTreeNode* pNode4 = CreateBinaryTreeNode( 4 ); BinaryTreeNode* pNode5 = CreateBinaryTreeNode( 5 ); BinaryTreeNode* pNode6 = CreateBinaryTreeNode( 6 ); BinaryTreeNode* pNode7 = CreateBinaryTreeNode( 7 ); ConnectTreeNodes( pNode1, pNode2, pNode3 ); ConnectTreeNodes( pNode2, pNode4, pNode5 ); ConnectTreeNodes( pNode3, pNode6, pNode7 ); Test( "Test1", pNode1, true ); DestroyTree( pNode1 ); } // 不是徹底二叉樹,可是平衡二叉樹 // 1 // / \ // 2 3 // /\ \ // 4 5 6 // / // 7 void Test2() { BinaryTreeNode* pNode1 = CreateBinaryTreeNode( 1 ); BinaryTreeNode* pNode2 = CreateBinaryTreeNode( 2 ); BinaryTreeNode* pNode3 = CreateBinaryTreeNode( 3 ); BinaryTreeNode* pNode4 = CreateBinaryTreeNode( 4 ); BinaryTreeNode* pNode5 = CreateBinaryTreeNode( 5 ); BinaryTreeNode* pNode6 = CreateBinaryTreeNode( 6 ); BinaryTreeNode* pNode7 = CreateBinaryTreeNode( 7 ); ConnectTreeNodes( pNode1, pNode2, pNode3 ); ConnectTreeNodes( pNode2, pNode4, pNode5 ); ConnectTreeNodes( pNode3, NULL, pNode6 ); ConnectTreeNodes( pNode5, pNode7, NULL ); Test( "Test2", pNode1, true ); DestroyTree( pNode1 ); } // 不是平衡二叉樹 // 1 // / \ // 2 3 // /\ // 4 5 // / // 6 void Test3() { BinaryTreeNode* pNode1 = CreateBinaryTreeNode( 1 ); BinaryTreeNode* pNode2 = CreateBinaryTreeNode( 2 ); BinaryTreeNode* pNode3 = CreateBinaryTreeNode( 3 ); BinaryTreeNode* pNode4 = CreateBinaryTreeNode( 4 ); BinaryTreeNode* pNode5 = CreateBinaryTreeNode( 5 ); BinaryTreeNode* pNode6 = CreateBinaryTreeNode( 6 ); ConnectTreeNodes( pNode1, pNode2, pNode3 ); ConnectTreeNodes( pNode2, pNode4, pNode5 ); ConnectTreeNodes( pNode5, pNode6, NULL ); Test( "Test3", pNode1, false ); DestroyTree( pNode1 ); } // 1 // / // 2 // / // 3 // / // 4 // / // 5 void Test4() { BinaryTreeNode* pNode1 = CreateBinaryTreeNode( 1 ); BinaryTreeNode* pNode2 = CreateBinaryTreeNode( 2 ); BinaryTreeNode* pNode3 = CreateBinaryTreeNode( 3 ); BinaryTreeNode* pNode4 = CreateBinaryTreeNode( 4 ); BinaryTreeNode* pNode5 = CreateBinaryTreeNode( 5 ); ConnectTreeNodes( pNode1, pNode2, NULL ); ConnectTreeNodes( pNode2, pNode3, NULL ); ConnectTreeNodes( pNode3, pNode4, NULL ); ConnectTreeNodes( pNode4, pNode5, NULL ); Test( "Test4", pNode1, false ); DestroyTree( pNode1 ); } // 樹中只有1個結點 void Test5() { BinaryTreeNode* pNode1 = CreateBinaryTreeNode( 1 ); Test( "Test6", pNode1, true ); DestroyTree( pNode1 ); } // 樹中沒有結點 void Test6() { Test( "Test7", NULL, true ); } int main() { Test1(); Test2(); Test3(); Test4(); Test5(); Test6(); return 0; }
一個整數數組裏除了兩個數字以外,其餘的數字都出現了兩次。請寫程序找出這兩個只出現
一次的數字。要求時間複雜度是O(n),空間複雜度是O(1)。
#include <iostream> #include <stdio.h> // 判斷數字num的第indexBit位是否是1 bool isBit1( int num, unsigned int indexBit ) { num = num >> indexBit; return ( num & 1 ); } // 找到num從右邊數起第一個是1的位 unsigned int FindFirstBitIs1( int num ) { int indexBit = 0; while( ( ( num & 1 ) == 0 ) && ( indexBit < 8 * sizeof( int ) ) ) { num = num >> 1; ++indexBit; } return indexBit; } void FindNumsAppearOnce( int data[], int length, int* num1, int* num2 ) { if( data == NULL || length < 2 ) return; int resultExclusiveOR = 0; for( int i = 0; i < length; ++i ) resultExclusiveOR ^= data[ i ]; unsigned int indexOf1 = FindFirstBitIs1( resultExclusiveOR ); *num1 = *num2 = 0; for( int j = 0; j < length; ++j ) { if( isBit1( data[ j ], indexOf1 ) ) *num1 ^= data[ j ]; else *num2 ^= data[ j ]; } } void Test( const char* testName, int data[], int length, int expected1, int expected2 ) { if( testName != NULL ) printf( "%s begins: ", testName ); int result1, result2; FindNumsAppearOnce( data, length, &result1, &result2 ); if( ( expected1 == result1 && expected2 == result2 ) || ( expected2 == result1 && expected1 == result2 ) ) printf( "Passed.\n\n" ); else printf( "Failed.\n\n" ); } void Test1() { int data[] = { 2, 4, 3, 6, 3, 2, 5, 5 }; Test( "Test1", data, sizeof( data ) / sizeof( int ), 4, 6 ); } void Test2() { int data[] = { 4, 6 }; Test( "Test2", data, sizeof( data ) / sizeof( int ), 4, 6 ); } void Test3() { int data[] = { 4, 6, 1, 1, 1, 1 }; Test( "Test3", data, sizeof( data ) / sizeof( int ), 4, 6 ); } int main() { Test1(); Test2(); Test3(); return 0; }