問題:有乙個m*n的二維陣列,從外到內按照順時針填充,並將結果列印出來。
據個例子: 3 * 4 的陣列,填充結果為
1 2 3 4
10 11 12 5
9 8 7 6
我們可以來的直接點,既然題目要求我們順時針填充,那麼我們就這樣把這個陣列填充滿就好了。
一般情況下,下標的遞增都是線性單向的。例如x作為下標,迴圈的過程中就是x++之類的。
但是,這個問題無非是把乙個線性的遞增關係變成了乙個區間函式,對於不同的情況,我們遞增偏差不同。
那二維陣列舉例,對於從左到右,假設原始座標是(x,y),那麼下乙個座標是(x,y+1)。
依次來說:從上到下 (x,y) -> (x+1,y)
從右到左 (x,y) -> ( x, y - 1 )
從下到上 (x,y) -> (x-1,y)
所以,我們可以總結出這樣的遞增資料:
int directionmap[2] = , // left -> right
, // top -> bottom
, // right -> left
, // bottom -> top
};
而且,我們可以發現,由於是順時針填充,所以,填充的變換過程,永遠按照directionmap從大到小的順序變化。
於是,有如下的程式:
#include #include #include using namespace std;
namespace cycleprint
inline int operator()( int x, int y ) const
private:
int m_ncolumn;
};
void deletearray( int* array )
}void doprint( int row , int column )
, // left -> right
, // top -> bottom
, // right -> left
, // bottom -> top
};
int currentnumber = 1;
int currentdirection = 0;
indexmap im(column);
int x(0) , y(0);
while( currentnumber <= row * column )
else
} for ( int i = 0 ; i < row ; ++i )
cout << endl;
} }
};
int main(int argc, char* argv)
通過一定的觀察,我們發現:
當我們把大小為m*n,初始座標點為(x,y)的乙個二維矩陣的一圈填滿之後,
剩下的任務是繼續填滿乙個大小為(m-2)*(n-2),初始座標為(x+1,y+1)
所以,這個問題也適用於遞迴的方式解決辦法,我們只要精確的找對的遞迴出口的條件就好。
下面,考慮到遞迴的方式比較適用於fp思維,所以,用f#的方式給出遞迴的實現。
主要思路已經說明了,關於具體的解法,我這裡首先根據輸入引數 初始下標x,y和要填充的矩陣大小,對映成對應的填充順序座標。
然後直接遞迴子矩陣,知道找出所有的順序座標,隨後填充到乙個二維陣列裡面,最後輸出。
maptocoordinate為主要的對映函式。
// learn more about f# at
module cycleprint
type direction =
| left2right
| top2bottom
| right2left
| bottom2top
let rec maptocoordinate x y row column =
let makecoordinatefromdirection direction=
match direction with
| left2right when column > 0 && row > 0 ->
[ 0 .. column - 1 ] |> list.map ( fun offset -> ( x , y + offset) )
| top2bottom when column > 0 && row > 2 ->
[ 0 .. row - 2 - 1 ] |> list.map ( fun offset -> ( x + 1 + offset, y + column - 1 ) )
| right2left when column > 0 && row > 1 ->
[ 0 .. -1 .. -( column - 1 ) ] |> list.map ( fun offset -> ( x + row - 1 , y + column - 1 + offset) )
| bottom2top when column > 0 && row > 2 ->
[ 0 .. -1 .. - ( row - 2 - 1) ] |> list.map ( fun offset -> ( x + row - 1 - 1 + offset, y ) )
| _ ->
let head = [ left2right ; top2bottom ; right2left ; bottom2top ]
|> list.map makecoordinatefromdirection
match head with
| ->
let doprint row column =
let matrix = array2d.create row column 0
maptocoordinate 0 0 row column
|> list.zip [ 1 .. (row*column) ]
|> list.iter (fun ( num , (x,y) ) -> matrix.[x,y] <- num )
for x in 0..(row-1) do
for y in 0..(column-1) do
printf "%4d" matrix.[x,y]
printfn ""
let main ( args : string ) =
doprint 4 8
0
劍指offer 二維陣列中的查詢 一題多解
題目 在乙個二維陣列中 每個一維陣列的長度相同 每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成乙個函式,輸入這樣的乙個二維陣列和乙個整數,判斷陣列中是否含有該整數。方法一 暴力法 思路 遍歷二維陣列,若有相等的值則返回true,遍歷結束沒有相等的值則返回false。時...
每日一題 二維陣列中的查詢
題目 在乙個二維陣列中,每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成乙個函式,輸入這樣的乙個二維陣列和乙個整數,判斷陣列中是否含有該整數輸入描述 array 待查詢的二維陣列 target 查詢的數字 輸出描述 查詢到返回true,查詢不到返回false 思路一 二...
劍指offer 二維陣列查詢 每日一題
在乙個二維陣列中,每一行都按照從左到右遞增的順序排列,每一列都按照從上到下遞增順序排列。請完成乙個函式,輸入這樣的乙個二維陣列和乙個整數,判斷陣列中是否含有該整數。測試用例 1 2 8 9 2 4 9 12 4 7 10 13 6 8 11 15 查詢7輸出 9,因為9 4 2 1 第三行第二列 根...