一、概要
本文介紹了有關陣列的演算法第四部分的Java
程式碼實現,所有程式碼均可通過 線上編譯器 直接執行,演算法目錄:
- 求陣列當中的最長遞增子序列(求陣列當中的最長遞減子序列)
- 區間重合判斷
- 一個整數陣列,長度為
n
,將其分為m
份,使各份的和相等,求m
的最大值
二、程式碼實現
2.1 求陣列當中的最長遞增子序列
程式碼實現
class Untitled {
//查詢最長遞增子序列。
static void searchMaxIncSubArray(int p[], int length) {
//maxValue[i]表示長度為i的遞增子序列的最大元素的最小值。
int[] maxValue = new int[length+1];
maxValue[1] = p[0];
int k=1;
for (int i=1; i<length; i++) {
if (p[i] > maxValue[k]) {
k++;
maxValue[k] = p[i];
} else if (p[i] == maxValue[k]) { //如果p[i]和maxValue[k],那麼越過。
continue;
} else { //如果p[i]小於maxValue[k]。
if (p[i] < maxValue[1]) {
maxValue[1] = p[i];
continue;
}
int first = 1;
int last = k;
//二分查詢:目的是在maxValue陣列中找到大於p[i]的第一個元素,如果它大於p[i],那麼就替換它。
while (first < last) {
int mid = (last-first) >> 1;
if (maxValue[first+mid] < p[i]) {
first=first+mid+1;
} else if (maxValue[first+mid] > p[i]) {
last=first+mid;
} else {
first=first+mid+1;
}
}
//進行替換。
if (p[i] < maxValue[first]) {
p[i] = maxValue[first];
}
}
}
System.out.println("k=" + k);
}
public static void main(String[] args) {
int[] p = {1,2,31,4,20,-7,8};
searchMaxIncSubArray(p, p.length);
}
}
複製程式碼
執行結果
>> k=3
複製程式碼
2.2 區間重合判斷
程式碼實現
class Untitled {
static class Area {
int start;
int end;
Area(int start, int end) {
this.start = start;
this.end = end;
}
}
//首先對區間進行排序,按照start進行遞增排序。
static void sortArea(Area areas[], int start, int end) {
if (start==end) {
return;
}
int mid = start;
Area midValue = areas[start];
for (int i=start+1; i<=end; i++) {
Area data = areas[i];
if (data.start < midValue.start) {
mid++;
areas[i] = areas[mid];
areas[mid] = data;
}
}
Area temp = areas[mid];
areas[mid] = areas[start];
areas[start] = temp;
if (mid > start) {
sortArea(areas, start, mid-1);
}
if (mid < end) {
sortArea(areas, mid+1, end);
}
}
//合併區間,使得兩個區間之間互不重合。
static int mergeArea(Area areas[], int len) {
int lastIndex = 0;
Area lastArea = areas[0];
for (int i=1; i<len; i++) {
Area cur = areas[i];
if (cur.start <= lastArea.end) {
if (cur.end > lastArea.end) {
lastArea.end = cur.end;
areas[lastIndex] = lastArea;
}
} else {
lastArea = cur;
lastIndex++;
areas[lastIndex] = lastArea;
}
}
return lastIndex+1;
}
//通過二分查詢,確定目標區間是否在其範圍之內。
static boolean searchArea(Area areas[], int areasLen, Area target) {
int startIndex = 0;
int endIndex = areasLen-1;
while (startIndex <= endIndex) {
int mid = (startIndex+endIndex) >> 1;
Area midValue = areas[mid];
if (target.start < midValue.start) {
if (target.end > midValue.end) {
return false;
} else {
endIndex=mid-1;
}
} else if (target.start >= midValue.start && target.start <= midValue.end) {
if (target.end <= midValue.end) {
return true;
} else {
return false;
}
} else {
startIndex = mid+1;
}
}
return false;
}
static void printArea(Area areas[], int len) {
for (int i=0; i<len; i++) {
Area area = areas[i];
System.out.println("start=" + area.start + ",end=" + area.end);
}
}
public static void main(String[] args) {
Area areas[] = new Area[] {
new Area(1, 3),
new Area(5, 9),
new Area(2, 4),
new Area(10, 11),
};
sortArea(areas, 0, areas.length-1);
System.out.println("- 排序結果 -");
printArea(areas, areas.length);
int mergeLen = mergeArea(areas, areas.length);
System.out.println("- 合併結果 -");
printArea(areas, mergeLen);
Area target = new Area(3, 4);
System.out.println("處於區間內=" + searchArea(areas, mergeLen, target));
}
}
複製程式碼
執行結果
>> - 排序結果 -
>> start=1,end=3
>> start=2,end=4
>> start=5,end=9
>> start=10,end=11
>> - 合併結果 -
>> start=1,end=4
>> start=5,end=9
>> start=10,end=11
>> 處於區間內=true
複製程式碼
2.3 一個整數陣列,長度為 n,將其分為 m 份,使各份的和相等,求 m 的最大值
程式碼實現
class Untitled {
static Boolean testGroup(int p[], int aux[], int pLen, int groupLen, int curSum, int groupSum, int groupID){
if (curSum < 0)
return false;
if (curSum == 0){
groupID++;
curSum = groupSum;
if (groupID == groupLen+1) {
return true;
}
}
for (int i=0; i<pLen; i++){
if (aux[i] != 0) {
continue;
}
aux[i] = groupID;
if (testGroup(p, aux, pLen, groupLen, curSum-p[i], groupSum, groupID)) {
return true;
}
aux[i] = 0;
}
return false;
}
static void maxGroup(int p[], int len) {
int aux[] = new int[len];
int sum = 0;
for (int i=0; i<len; i++) {
aux[i] = 0;
sum += p[i];
}
for (int m=len; m>=2; m--) {
if (sum%m != 0) {
continue;
}
if (testGroup(p, aux, len, m, sum/m, sum/m, 1)) {
System.out.println("m=" + m);
for (int i=0; i<len; i++) {
System.out.println("aux[" + i + "]=" + aux[i]);
}
}
}
}
public static void main(String[] args) {
int a[] = {3,2,4,3,6};
maxGroup(a, a.length);
}
}
複製程式碼
執行結果
>> m=3
>> aux[0]=1
>> aux[1]=2
>> aux[2]=2
>> aux[3]=1
>> aux[4]=3
複製程式碼
更多文章,歡迎訪問我的 Android 知識梳理系列:
- Android 知識梳理目錄:www.jianshu.com/p/fd82d1899…
- Android 面試文件分享:www.jianshu.com/p/8456fe6b2…