JZ6 旋轉數組的最小數字
(簡單)
題目
描述
把一個數組最開始的若幹個元素搬到數組的末尾,我們稱之為數組的旋轉。
輸入一個非遞減排序的數組的一個旋轉,輸出旋轉數組的最小元素。
NOTE:給出的所有元素都大于0,若數組大小為0,請傳回0。
示例
輸入:
[3,4,5,1,2]
傳回值:
1
思路
本題中關于此原始數組的其中一個描述是非遞減排序的數組,這個名詞我們千萬不能了解錯了,非遞減排序的正确意思是,資料遞增排列,但并非單調遞增(因為可能有多個相等的資料的情況),即數列整體上從小到大并且允許其中有相等的情況出現。
而此題中的旋轉數組,也就是根據非遞減排序的數組經過旋轉生成的,是以,針對 [1, 2, 3, 4, 5]這樣一個非遞減排序的數組,經過旋轉後的全部可能排列情況為:
12345
23451
34512
45123
51234
因為旋轉後的數組,在整體上,仍是有序的,并且這種有序的性質是可能集中有序于左部分,或右部分,是以,我們不難聯想到二分法,我們完全可以定義一個 start 起始下标,end 末尾下标,mid 中間下标。我們在編碼的循環中,以 start != end 為終止循環的條件,并在循環體中不斷縮小查找範圍,最終定位最小元素值。接下來我們便可以根據上面的排序樣例分析,在循環體中,如果中值大于尾值,那麼我們可以判定最小值在位置的右半部分,并且最小值不可能是中值或者說不可能和中值相等,是以我們便可将頭值下标指向中值下标的下一位,若中值小于尾值,則最小值在左部分,并且需将尾下标指向中值下标,因為中值也在最小值的可能範圍内。最後還需注意的一點就是題目中的 NOTE:若數組大小為0,則傳回0。
上述算法思想也可以再進行進一步的優化,就12345這種排序情況,我們沒必要再進入循環體比較,因為此題情況特殊,是由非遞減排序的數組而生成的旋轉數組,是以,當程式遇到這種整體遞增(可能有等值,但不影響)的情況,隻需通過 array[start] 小于 array[end] 成立,即可判斷為此種情況,直接傳回頭值即可。另外,如果在其他情況中,循環體中出現了 array[mid] 等于 array[end] 的情況(這也意味着原始的非遞減排序有資料相等的情況出現),我們可将尾下标進行一次左移動,進而避免之後不必要的判斷,提高算法的執行效率,而此題也是卡的這一點,因為我在用 Java 代碼進行送出時,沒有這一步優化是會運作逾時的。
實作
class Solution3 {
public int minNumberInRotateArray(int [] array) {
if (array.length == 0) {
return 0;
}
int start = 0;
int end = array.length - 1;
int mid = 0;
while (start != end) {
// 優化1
if (array[start] < array[end]) {
return array[start];
}
//
mid = (start + end) / 2;
if (array[mid] > array[end]) {
start = mid + 1;
} else if (array[mid] < array[end]) {
end = mid;
}
// 優化2
else {
end--;
}
//
}
return array[start];
}
}
public class JZ6旋轉數組的最小數字 {
public static void main(String[] args) {
Solution3 solution3 = new Solution3();
int[] array = new int[]{3, 4, 5, 1, 2};
int[] array2 = new int[]{4, 5, 1, 2, 3};
int[] array3 = new int[]{5, 1, 2, 3, 4};
int[] array4 = new int[]{3, 4, 1, 2};
int[] array5 = new int[]{2, 1};
int[] array6 = new int[]{1, 2, 3, 4};
System.out.println(solution3.minNumberInRotateArray(array));
System.out.println(solution3.minNumberInRotateArray(array2));
System.out.println(solution3.minNumberInRotateArray(array3));
System.out.println(solution3.minNumberInRotateArray(array4));
System.out.println(solution3.minNumberInRotateArray(array5));
System.out.println(solution3.minNumberInRotateArray(array6));
}
}
JZ16 合并兩個排序的連結清單
(簡單)
題目
描述
輸入兩個單調遞增的連結清單,輸出兩個連結清單合成後的連結清單,當然我們需要合成後的連結清單滿足單調不減規則。
示例
輸入:
{1,3,5},{2,4,6}
傳回值:
{1,2,3,4,5,6}
思路
此題為常見的兩連結清單合并操作,隻是在合并的同時要求結點值單調不遞減。
實作
class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
@Override
public String toString() {
return "ListNode{" +
"val=" + val +
", next=" + next +
'}';
}
}
class Solution6 {
public static ListNode Merge(ListNode list1,ListNode list2) {
if (list1 == null && list2 == null) {
return null;
} else if (list1 == null) {
return list2;
} else if (list2 == null) {
return list1;
} else {
ListNode mergeList = new ListNode(0);
ListNode tempList = mergeList;
while (list1 != null && list2 != null) {
if (list1.val > list2.val) {
tempList.next = new ListNode(list2.val);
tempList = tempList.next;
list2 = list2.next;
} else {
tempList.next = new ListNode(list1.val);
tempList = tempList.next;
list1 = list1.next;
}
}
while (list1 != null) {
tempList.next = new ListNode(list1.val);
tempList = tempList.next;
list1 = list1.next;
}
while (list2 != null) {
tempList.next = new ListNode(list2.val);
tempList = tempList.next;
list2 = list2.next;
}
return mergeList.next;
}
}
}
public class JZ16合并兩個排序的連結清單 {
public static void main(String[] args) {
ListNode list1 = new ListNode(1);
//ListNode OList1 = list1;
//list1 = list1.next;
//list1 = new ListNode(3);
//list1 = list1.next;
//list1 = new ListNode(5);
list1.next = new ListNode(3);
list1.next.next = new ListNode(5);
ListNode list2 = new ListNode(2);
//ListNode OList2 = list2;
//list2 = list2.next;
//list2 = new ListNode(4);
//list2 = list2.next;
//list2 = new ListNode(6);
list2.next = new ListNode(4);
list2.next.next = new ListNode(6);
ListNode merge = Solution6.Merge(list1, list2);
showList(merge);
}
private static void showList(ListNode merge) {
while (merge != null) {
System.out.print(merge.val);
if (merge.next != null) {
System.out.print("——");
}
merge = merge.next;
}
}
}