🦍
配列反転の術(【LeetCode】189. Rotate Array 関連)
「配列反転の術」はLeetcodeの問題を解く際に、かなーり強い味方になります。
数学の公式のように使い方を覚えちゃいましょう!
簡単なのに、けっこう強力ですぜぇ!
問題
整数配列 nums が与えられたとき、配列を反転させてください。
例 1:
入力:
nums = [1,2,3,4]
出力:
[4,3,2,1]
まずは2つのポインターを準備します。
startポインター(sと省略)、endポインター(eと省略)
こんなかんじです。
e
↓
[1,2,3,4]
↑
s
sは右側に進み、eは左側に進みます。
配列のインデックスで言うと、sは++されていき、eは--されていきます。
では、この状態でそれぞれが指し示すポインターを入れ替えて(スワップ)みましょう。
e
↓
[4,2,3,1]
↑
s
そして、それぞれのポインターを進めます。
sは右側へ、eは左側へ進みます。
e
↓
[4,2,3,1]
↑
s
先程と同じようにして、それぞれが指し示すポインターを入れ替えて(スワップ)みましょう。
e
↓
[4,3,2,1]
↑
s
そして、入れ替え後はそれぞれのポインターを進めますので、進めてみましょう。
e
↓
[4,3,2,1]
↑
s
どうでしょうか?
反転できていますね。やった!!
反転できていますので、ここで完了となります。
なんとなくですが、アルゴリズムが見えてきましたね。
解法(実装)
package main
import "fmt"
// 入力で配列を受けて、反転させた配列を返す
func reverse(nums []int) []int {
start := 0
end := len(nums) - 1
for start < end {
// 要素を入れ替える。
// Go言語の場合は、一時的にtempなどの変数に格納しなくても一気に入れ替えができる!
nums[start], nums[end] = nums[end], nums[start]
start++
end--
}
return nums
}
func main() {
nums1 := []int{1, 2, 3, 4, 5, 6, 7}
nums1_rev := reverse(nums1)
fmt.Println("nums1_rev =", nums1_rev)
}
main.go 実行結果
nums1_rev = [7 6 5 4 3 2 1]
補足
for文のループ条件(for start < end)ですが、
下記が反転完了時の状態です。
startがendを追い越している形です。(最初はstartのほうが小さく、endのほうが大きかった。)
つまり、インデックスがendのほうが大きい間は処理を実行するということになります。
ですので、(for start < end)になります。
e
↓
[4,3,2,1]
↑
s
Discussion