データ構造とアルゴリズムのインタビューの質問: 整数配列 nums が与えられた場合、最大合計を持つ連続した部分配列を見つけ (部分配列には少なくとも 1 つの要素が含まれます)、その最大合計を返します。
はじめに: 整数配列 nums を指定して、合計が最大になる連続した部分配列を見つけて (部分配列には少なくとも 1 つの要素が含まれます)、その最大合計を返します。
アルゴリズムの実装アイデアは次のとおりです。
- 変数を使用して
ans
最終的な答えを保存し、変数を使用しcur
て連続する部分配列の現在の合計を保存します。 - 配列全体を走査し、各数値について、
cur
それ自体と(cur + nums[i])
の間の大きい値に更新します。cur
より大きい場合はans
、ans
に更新されますcur
。 - 配列を走査した後、
ans
最大の部分配列の合計を返します。
以下は、C++ を使用して最大の部分配列の合計を見つけるコードと詳細なコメントです。
#include <iostream>
#include <vector>
using namespace std;
int maxSubArray(vector<int>& nums) {
int ans = nums[0]; // 初始化最终答案
int cur = nums[0]; // 初始化当前连续子数组
for (int i = 1; i < nums.size(); ++i) {
cur = max(nums[i], cur + nums[i]); // 更新当前连续子数组和
ans = max(ans, cur); // 更新最终答案
}
return ans;
}
int main() {
vector<int> nums = {-2, 1, -3, 4, -1, 2, 1, -5, 4};
int ans = maxSubArray(nums);
cout << ans << endl; // 6
return 0;
}
ans
このアルゴリズムは配列全体を走査し、これまでに見つかった最適な連続サブシーケンスの合計を表す 2 つの変数の合計 (num[i] で終わる連続サブ配列のcur
合計) を維持します。各走査で、現在の値 num[i] と num[i]+cur の間の大きい値で cur を更新し、現在の部分配列 msum[i] の合計を見つけて ans と比較し、ans に記録します。最終的には戻り値を返します。答えとしては。ループの層が 1 つしかないため、このアルゴリズムの時間計算量は O(n) です。ans
cur
- Javaのバージョン
import java.util.Arrays;
public class Main {
public static int maxSubArray(int[] nums) {
int ans = nums[0]; // 初始化最终答案
int cur = nums[0]; // 初始化当前连续子数组
for (int i = 1; i < nums.length; ++i) {
cur = Math.max(nums[i], cur + nums[i]); // 更新当前连续子数组和
ans = Math.max(ans, cur); // 更新最终答案
}
return ans;
}
public static void main(String[] args) {
int[] nums = {
-2, 1, -3, 4, -1, 2, 1, -5, 4};
int ans = maxSubArray(nums);
System.out.println(ans); // 6
}
}