演算法練習:一維陣列旋轉
阿新 • • 發佈:2019-01-02
題目描述:求一個一維陣列向右旋轉K個位置後的結果。比如,一維陣列{1, 2, 3, 4, 5},當k = 2時,求得的結果為{4, 5, 1, 2, 3}。要求常數級空間複雜度,允許修改原有陣列。
一、使用額外的空間(在不要求常數級空間複雜度的情況下)
這樣很簡單,使用一個額外的空間,儲存原有陣列的元素,然後可以錯位複製原有陣列
元素,即可達到題目的要求。比如陣列{1, 2, 3, 4, 5},當k = 2時,先將4,5複製到結果陣列,然後將1,2,3複製到結果陣列的後面部分。
//使用額外空間進行陣列旋轉 void RotateArrayK_Ext( int nArray[], int nCount, int k ) { if ( nArray == NULL || nCount <= 0 || k < 0 || k > nCount ) return; int* pArrayTemp = new int[nCount]; if ( NULL == pArrayTemp ) return; //備份資料 for ( int i = 0; i < nCount; ++i ) { pArrayTemp[i] = nArray[i]; } //進行錯位複製 int i = 0; for ( i = 0; i < k; ++i ) { nArray[i] = pArrayTemp[nCount-k+i]; } for ( int j = 0; i < nCount; ++i ) { nArray[i] = pArrayTemp[j++]; } }
函式RotateArrayK_Ext的空間複雜度為O(n),時間複雜度也為O(n),顯然,在空間複雜度這一塊是不符合題目要求的。
二、常數級空間複雜度且允許修改原有陣列
在此要求下,我們可以對陣列進行三次反轉,從而求得結果。三次反轉陣列:第一次反轉整個陣列;第二次反轉陣列前K個數;第三次反轉剩下的數。例如:
一維陣列{1, 2, 3, 4, 5},k = 2
第一次反轉:5,4,3,2,1
第二次反轉:4,5,3,2,1
第三次反轉:4,5,1,2,3
程式程式碼如下:
//反轉陣列 bool ReverseArray( int nArray[], int nCount, int nStart, int nEnd ) { if ( nArray == NULL || nCount <= 0 ) return false; if ( nStart < 0 || nStart >= nCount ) return false; if ( nEnd < 0 || nEnd >= nCount ) return false; while( nStart < nEnd ) { int nTemp = nArray[nStart]; nArray[nStart] = nArray[nEnd]; nArray[nEnd] = nTemp; ++nStart; --nEnd; } return true; } //對陣列實施三次反轉來進行陣列的旋轉 void RotateArrayK( int nArray[], int nCount, int k ) { if ( nArray == NULL || nCount <= 0 || k < 0 || k > nCount ) return; //反轉整個陣列 ReverseArray( nArray, nCount, 0, nCount - 1 ); //反轉前K個數 ReverseArray( nArray, nCount, 0, k - 1 ); //反轉剩下的數 ReverseArray( nArray, nCount, k, nCount - 1 ); }
此演算法擁有常數級的空間複雜度,因為演算法裡執行了三次反轉陣列,反轉陣列都是線上性時間裡完成的,所以此演算法的時間複雜度為O(n)。
系列文章說明:
1.本系列文章[演算法練習],僅僅是本人學習過程的一個記錄以及自我激勵,沒有什麼說教的意思。如果能給讀者帶來些許知識及感悟,那是我的榮幸。
2.本系列文章是本人學習陳東鋒老師《進軍矽谷,程式設計師面試揭祕》一書而寫的一些心得體會,文章大多數觀點均來自此書,特此說明!
3.文章之中,難免有諸多的錯誤與不足,歡迎讀者批評指正,謝謝.
作者:山丘兒
轉載請標明出處,謝謝。原文地址:http://blog.csdn.net/s634772208/article/details/46417297