🦍

配列反転の術(【LeetCode】189. Rotate Array 関連)

2024/12/25に公開

「配列反転の術」は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