筆試面試演算法經典--連續子陣列的最大乘積及連續子陣列的最大和(Java)
阿新 • • 發佈:2019-01-08
1. 子陣列的最大和
輸入一個整形陣列,數組裡有正數也有負數。陣列中連續的一個或多個整陣列成一個子陣列,每個子陣列都有一個和。求所有子陣列的和的最大值。例如陣列:arr[]={1, 2, 3, -2, 4, -3 } 最大子陣列為 {1, 2, 3, -2, 4} 和為8。
解法1(時間複雜度O(N * N)空間複雜度O(1))
求出所有的子陣列的和,比較選擇出最大值。利用雙重迴圈就可以遍歷到所有的子陣列。
public static void maxSum1(int arr[])
{
int max=0,sum;
for(int i=0;i<arr.length ;i++)
{
sum=0;
for(int j=i;j<arr.length;j++)
{
//遍歷陣列的所有子陣列,並將子陣列的最大和儲存在max中。
sum+=arr[j];
max=Math.max(max, sum);
//max儲存最大的子陣列的和
}
}
System.out.println(max);
}
解法2(動態規劃時間複雜度O(N)空間複雜度O(1))
遍歷陣列,用 sum 儲存子陣列的和,當 sum<0 時 將 arr[i] 賦值給 sum,用 max 儲存最大值。
public static void maxSum(int arr[])
{
int max=0,sum=0;
for(int i=0;i<arr.length;i++)
{
if(sum<=0)
{
sum=arr[i];
//如果 sum<0 重新賦值
}
else {
sum+=arr[i];
}
max=Math.max(sum, max);
//將最大值儲存在max中。
}
System.out.println(max);
}
2. 子陣列的最大乘積
輸入一個整形陣列,數組裡有正數也有負數。陣列中連續的一個或多個整陣列成一個子陣列,每個子陣列都有一個和。求所有子陣列的和的最大值。例如陣列:arr[]={1, 2, 3, -2, 4, 3 } 最大子陣列為 {4,3} 積為12。
解法1(時間複雜度O(N * N)空間複雜度 O(1)):
跟上面求最大子陣列的和類似,利用雙重迴圈遍歷所有的子陣列,求出所有子陣列中值最大的。
public static void maxproduct(int arr[])
{
if(arr==null||arr.length==0)
return;
//如果陣列為 null 或者長度為0直接返回
int max=0,product=1;
//max儲存子陣列的最大乘積,product 用來儲存每一個子陣列的積
for(int i=0;i<arr.length;i++)
{
product=1;
for(int j=i;j<arr.length;j++)
{
product*=arr[j];
max=Math.max(product, max);
//max儲存最大的子陣列乘積
if(product==0)
break;
//如果當前子陣列的乘積為0則以當前陣列為頭的後序陣列的積全為0不用求。
}
}
System.out.println(max);
}
解法2(動態規劃 時間複雜度O(N )空間複雜度 O(1)):
跟上面求最大子陣列的和類似,利用雙重迴圈遍歷所有的子陣列,求出所有子陣列中值最大的。以arr[i] 結尾的最大值可能由前面的以arr[i-1]結尾的 最大 負值,最大正數,和arr[i] 產生。例如陣列:{2,-3,-4}以-4結尾的最大值,就是3*2=-6,與-4 相乘產生的。
public static void maxSubProduct(int arr[])
{
if(arr==null||arr.length==0)
return ;
int max=arr[0],min=arr[0],maxend,result=0;
for(int i=1;i<arr.length;i++)
{
//最大值的來源有三種,如果arr[i]是正數,肯定與前面的最大值相乘得到最大值,
//如果arr[i]是負數就會與前面的最小值相乘產生最大值。如果前面的為0或者負數,
//arr[i]本身可能是最大值。
maxend=Max(max*arr[i],min*arr[i],arr[i]);
//maxend 儲存最大值
min=Min(max*arr[i], min*arr[i], arr[i]);
//用於儲存最小的負值,為下一個最大值最準備
max=maxend;
result=Math.max(result, max);
}
System.out.println(result);
}
public static int Max(int a,int b,int c)
{
//返回 a b c 中的最大值
a=Math.max(a, b);
a=Math.max(a, c);
return a;
}
public static int Min(int a,int b,int c)
{
//返回 a b c 中的最小值
a=Math.min(a, b);
a=Math.min(a, c);
return a;
}