11. 旋转数组的最小数字
算法思想:
使用二分法进行查找。
将数组看作左右两个数组,设置两个指针i,j分别指向数组首尾,若n[mid]>n[j],说明mid在左边数组中,令i=mid+1;若n[mid]<n[j],说明mid在右边数组中,令j=mid;若n[mid]=n[j],无法判断mid在哪边数组,j–减少区间范围。
详细题解(关于为什么不和i进行比较/j–的正确性证明)
代码:
class Solution {
public int minArray(int[] numbers) {
int i = 0, j = numbers.length - 1;
while(i < j){
int mid = (i + j) / 2;
if(numbers[mid] > numbers[j]){
i = mid + 1;
}else if(numbers[mid] < numbers[j]){
j = mid;
}else{
j--;
}
}
return numbers[i];
}
}
改进:
n[mid]=n[j]时,可以直接用线性查找。
class Solution {
public int minArray(int[] numbers) {
int i = 0, j = numbers.length - 1;
while(i < j){
int mid = (i + j) / 2;
if(numbers[mid] > numbers[j]){
i = mid + 1;
}else if(numbers[mid] < numbers[j]){
j = mid;
}else{
for(int k = i+1; k < numbers.length; ++k){
if(numbers[k] < numbers[i]){
i=k;
}
}
return numbers[i];
}
}
return numbers[i];
}
}
25. 合并两个排序的链表
代码:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode head = new ListNode(0);
ListNode l3 = head;
while(l1 !=null && l2 !=null){
if(l1.val < l2.val){
l3.next = l1;
l3 = l1;
l1 = l1.next;
}else{
l3.next = l2;
l3 = l2;
l2 = l2.next;
}
}
if(l1 == null && l2 != null){
while(l2 != null){
l3.next = l2;
l3 = l2;
l2 = l2.next;
}
}
if(l2 == null && l1 != null){
while(l1 != null){
l3.next = l1;
l3 = l1;
l1 = l1.next;
}
}
return head.next;
}
}
改进:
最后不需要逐个遍历,直接将l3指向非空链表即可。
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode head = new ListNode(0);
ListNode l3 = head;
while(l1 !=null && l2 !=null){
if(l1.val < l2.val){
l3.next = l1;
l1 = l1.next;
}else{
l3.next = l2;
l2 = l2.next;
}
l3 = l3.next;
}
l3.next = l1 !=null ? l1 : l2;
return head.next;
}
}