快速排序:
思路.
1.确认分割点,可以选择q[l] 中中点或者 最右的端点。
2.使得分割点的左边小于等于分割点,右边大于等于分割点
3.递归处理左右两端
-
#include
-
#define LEN 12 // 宏定义数组的大小
-
static int tmp[LEN] = {0};// 设置临时数组
-
// 打印数组
-
void print_array(int *array)
-
{
-
int index = 0;
-
<div>printf("\narray:\n");</div>
</div>
11.
<div>for (; index < LEN; index++){</div>
</div>
12.
<div>printf(" %d, ", *(array + index));</div>
</div>
13.
<div>}</div>
</div>
14.
<div>printf("\n");</div>
</div>
15.
<div>}</div>
</div>
17.
<div>// 把两个有序的数组排序成一个数组</div>
</div>
18.
<div>void _mergeSort(int *array, int start, int middle, int end)</div>
</div>
19.
<div>{</div>
</div>
20.
<div>int first = start;</div>
</div>
21.
<div>int second = middle + 1;</div>
</div>
22.
<div>int index = start;</div>
</div>
23.
<div>while ((first <= middle) && (second <= end)){</div>
</div>
24.
<div>if (array[first] >= array[second])</div>
</div>
25.
<div>tmp[index++] = array[second++];</div>
</div>
26.
<div>else</div>
</div>
27.
<div>tmp[index++] = array[first++];</div>
</div>
28.
<div>}</div>
</div>
29.
<div>while(first <= middle) tmp[index++] = array[first++];</div>
</div>
30.
<div>while(second <= end) tmp[index++] = array[second++];</div>
</div>
32.
<div>for (first = start; first <= end; first++)</div>
</div>
33.
<div>array[first] = tmp[first];</div>
</div>
34.
<div>}</div>
</div>
36.
<div>// 递归划分数组</div>
</div>
37.
<div>void mergeSort(int *array, int start, int end)</div>
</div>
38.
<div>{</div>
</div>
39.
<div>if (start >= end)</div>
</div>
40.
<div>return;</div>
</div>
41.
<div>int middle = ((end + start) >> 1);</div>
</div>
42.
<div>mergeSort(array, start, middle);// 递归划分左边的数组</div>
</div>
43.
<div>mergeSort(array, middle+1, end);// 递归划分右边的数组</div>
</div>
44.
<div>_mergeSort(array, start, middle, end);// 对有序的两个数组进行合并成一个有序的数组</div>
</div>
45.
<div>}</div>
</div>
47.
<div>int main(void)</div>
</div>
48.
<div>{</div>
</div>
49.
<div>int array[LEN] = {2, 1, 4, 0, 12, 520, 2, 9, 5, 3, 13, 14};</div>
</div>
50.
<div>print_array(array);</div>
</div>
51.
<div>mergeSort(array, 0, LEN-1);</div>
</div>
52.
<div>print_array(array);</div>
</div>
53.
<div>return 0;</div>
</div>
54.
<div>}</div>
</div>
算法2 :歸并排序:
思路:
1.找到分界點(終點(l+r)>>1)
2.遞歸排序左邊和右邊
3.合并兩個區間
时间复杂度的分析
n.Log2N (因为总共有Log2N层(每次从1-》n,每次变成原来的2被,因此可以用对数表示需要的次数,乘法银子的话,说明的是每层需要的时间))
整数二分:
单调性不是必要的
vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
大部分满足单调性;百分之95的情况满足二段性质;
两个模板;
区别:
1. 不同性质部分的端点的区间不一样(更具mid的值来更新);
2.mid的更新也不一样,在模板二的时候需要上取整,要不然会死循环
1.确定边界
2.编写框架
3.设计一个check函数(),一段满足这个性质,另一段不满足这个性质。因此是红色那段的模板
4.判断如何更新
5.如果l=mid,r=mid-1, 算mid的时候+1
public int mySqrt(int x)
{
int l = 0;
int r = x;
while (l < r)
{ int mid = l + r + 1 >> 1;
if (mid*mid > x)//因爲滿足的條件在左邊,所以不需要等於,如果這個條件成立,表示在的是綠顏色的部分,所以需要更新r的值 。表示紅色的部分,表示模板2,因此mid需要向上除;
r = mid-1;//否則需要更新l的值
else
{ l=mid; }
}
return l;
}
//https://www.acwing.com/blog/content/31/ 二分模板
Leetcode 35:
正確題解:
das
class Solution
{
public int searchInsert(int[] nums, int target)
{
if (nums.length == 0) return 0;
if (nums[nums.length - 1] < target)
return nums.length ; int l = 0; int r = nums.length - 1;
while (l < r)
{ int mid = l + r >> 1;
if (nums[mid] >= target)
{
r = mid;
}
else
{
l = mid + 1;
}
}
return l;
}
}
疑問點:到底什麽時候用模板一,什麽時候用模板2呀(應該是 兩個都可以做出來)
因爲num[mid]<=target的話,找到這個剛好等於的邊界也可以呀