Description du titre
HZ utilise parfois des questions professionnelles pour tromper ces majors non informatiques. Après que le groupe de test eut une réunion aujourd'hui, il reprit la parole: dans l'ancienne reconnaissance de formes unidimensionnelle, il est souvent nécessaire de calculer la somme maximale des sous-vecteurs continus. Lorsque les vecteurs sont tous positifs, le problème est résolu facilement. Cependant, si le vecteur contient des nombres négatifs, doit-il contenir un certain nombre négatif et s'attendre à ce que le nombre positif à côté de lui le rattrape? Par exemple: {6, -3, -2,7, -15,1,2,2}, la somme maximale des sous-vecteurs consécutifs est de 8 (à partir du 0e et se terminant par le 3e). Donnez un tableau et renvoyez la somme de ses plus grandes sous-séquences consécutives. Serez-vous dupe par lui? (La longueur du sous-vecteur est d'au moins 1)
Analyse thématique
Notez que la somme maximale des sous-vecteurs de 0 à i est ans [i], subRight [i] est la somme maximale de tous les sous-vecteurs se terminant par l'élément marqué i, qui peut être facilement obtenue, ans [i] = max (ans [ i-1], subRight [i]), car ans [i-1] est calculé à partir de tous les sous-vecteurs qui ne contiennent pas d'éléments du tableau [i], et subRight [i] est calculé à partir de tous les sous-vecteurs qui contiennent des éléments du tableau [i] Le vecteur est calculé.
Ensuite, le but de la question est de calculer ans [array.length-1], comment calculer un [i]? Utiliser ans [i] = max (ans [i-1], subRight [i]), puis comment calculer subRight [ i], tout d'abord subRight [0] doit être array [0], d'autres cas peuvent être dessinés comme ceci: si subRight [i-1]> 0, ajoutez array [i], si subRight [[i-1] < = 0, pour obtenir le plus grand, il vaut mieux former un sous-vecteur par tableau [i].
Par conséquent, la réponse peut être obtenue en un seul parcours, et la complexité temporelle est o (n)
Code
//子向量最大和ans[i]可以由Max(ans[i-1],以array[i]结尾的所有子向量最大和) 计算得出
public int FindGreatestSumOfSubArray(int[] array) {
if(array == null){
return 0;
}
int[] subRight = new int[array.length]; //这个数组的意义是 subRight[i] 为以array[i]结尾的所以子向量的最大和
for (int i = 0; i < subRight.length; i++) {
subRight[i] = 0; //初始化
}
int ans = Integer.MIN_VALUE;
for (int i = 0; i < array.length; i++) {
if(i == 0) //一开始先用array[0] 作为subRight[0]
subRight[i] = array[i];
else
subRight[i] = subRight[i-1]>0?subRight[i-1]+array[i]:array[i]; //不是开始,如果以左边元素结尾的子向量最大和大于0
// 则用左边结尾的子向量最大和加当前的值作为这里结尾的最大子向量最大和
//否则自己一个元素作为一个子向量
ans = Math.max(ans,subRight[i]); //与上一次得到的ans比较,相当于ans[i] = max(ans[i-1],subRight[i])
}
return ans;
}