今日の AI 筆記試験の問題:
AI Golang筆記試験中級問題https://bs.rongapi.cn/1702565828114780160/23
完全なタイトル:
整数配列とターゲット値を入力として受け取り、その合計がターゲット値と等しくなるように配列内の 2 つの数値を検索する関数を実装してください。関数はこれら 2 つの数値のインデックスを返す必要があります。インデックス 1 はインデックス 2 より小さい必要があります。各入力は 1 つの回答のみに対応し、同じ要素は再利用されないと想定できます。たとえば、配列 [2, 7, 11, 15] とターゲット値 9 の場合、nums[0] + nums[1] = 2 + 7 = 9 であるため、[0, 1] を返します。
アイデア:
この質問を受け取った後、私の最初の直感は、直接ループを二重にしてループして最初の数値を取得し、残りの数値の中から 2 番目の数値を検索し、見つかったら送信することです。
中間の質問として、まだ最適化を行う必要があります。
私の最適化のアイデアは、ループを作成したので、その後の検索を高速化するためにプロセス内の一部のデータをキャッシュすることは可能でしょうか?
最初は並べ替えを直接行うかどうか迷ったのですが、並べ替え自体にも計算が必要であり、この問題は完全な並べ替えを必要としないため、並べ替えよりも速いはずだと感じました。
この考え方に従うと、毎回値を比較するので、この処理中に元のデータをサイズに応じて 2 つの部分に分割できると思いますか?
このようにして、外層をループすると、より細かい粒度のグループが得られるので、次の比較では、小さすぎる値と大きすぎる値を直接無視して、ヒットした配列を 2 つに分割し、上の例のように、2 を 2 回目に検索する場合は、5 より下の最初のグループを比較するだけでよく、2 番目のグループは直接スキップします。
送信結果は最初のリンクにありますが、送信後、AI は次のように問題があると感じます。
回答評価:コードのロジックは基本的に正しいですが、いくつかの冗長な部分があります。グループ化の処理が簡素化され、マップを使用して走査された要素を保存することができるため、検索効率が向上します。
今思い出したのですが、mapを使えばいいのです… 位置と値の情報をマップに格納するエッジループです マップ内に対応する値があれば取り出して直接返します そうでない場合は、またループされてしまいます。
ただし、私のソリューションは、複数の可能な値を返す必要がある状況では依然として役に立ちます。皆さんが私を修正できるよう、改訂されたソリューションを投稿します。
type Group struct {
Seperator *int
Values [][2]int
}
func seperateGroup(seperator int, group *Group) (loc int, smallerGroup *Group, biggerGroup *Group, matched bool) {
smallerGroup, biggerGroup = &Group{
Seperator: &seperator,
}, &Group{
Seperator: group.Seperator,
}
for j := 0; j < len(group.Values); j++ {
if group.Values[j][0] == seperator {
return j, nil, nil, true
} else if group.Values[j][0] < seperator {
smallerGroup.Values = append(smallerGroup.Values, group.Values[j])
} else {
biggerGroup.Values = append(biggerGroup.Values, group.Values[j])
}
}
return 0, smallerGroup, biggerGroup, false
}
func recurse(loc int, arr []int, target int, groups ...*Group) []int {
if loc == len(arr)-1 {
return nil
}
var cur = arr[loc]
var remain = target - cur
var newGroups []*Group
i := 0
for ; i < len(groups); i++ {
if groups[i].Seperator == nil || remain <= *groups[i].Seperator {
remainLoc, smallerGroup, biggerGroup, matched := seperateGroup(remain, groups[i])
if matched {
return []int{loc, groups[i].Values[remainLoc][1]}
}
if i == 0 {
newGroups = []*Group{smallerGroup, biggerGroup}
} else {
newGroups = append(groups[:i-1], smallerGroup, biggerGroup)
}
break
}
}
if i < len(groups)-1 {
newGroups = append(newGroups, groups[i+1:]...)
}
return recurse(loc+1, arr, target, newGroups...)
}
// 主函数入口
func FindMatchGroup(arr []int, target int) []int {
if len(arr) < 2 {
return nil
}
var remain = &Group{}
for i := 1; i < len(arr); i++ {
remain.Values = append(remain.Values, [2]int{arr[i], i})
}
return recurse(0, arr, target, remain)
}