演算法作業03

第1題:Insertion Sort

請依據課本推導方式,當5個數字用insertion sort排序,data movement的平均值為多少?

j開始搬運一次的平均data movement

2j+3j+4j++j+1j=j+32

X=j=2nj+32=(n+8)(n1)4

n=5
X=(5+8)(51)4=13

Ans:13

請使用insertion sort排序 6,4,1,3,5。在四個回合中,每回合的data movement數量為何?總共的data movement數量為何?

第一回合

初始的序列:

a[0] a[1] a[2] a[3] a[4]
6 4 1 3 5
  1. 4X
  2. a0>X6

現在的序列:

a[0] a[1] a[2] a[3] a[4]
6 6 1 3 5

因為

j<0所以跳出迴圈

  1. Xa0

現在的序列:

a[0] a[1] a[2] a[3] a[4]
4 6 1 3 5

data movement:3
sum of data movement:3

第二回合

現在的序列:

a[0] a[1] a[2] a[3] a[4]
4 6 1 3 5
  1. 1X
  2. a1>X6

現在的序列:

a[0] a[1] a[2] a[3] a[4]
4 6 6 3 5
  1. a0>X4

現在的序列:

a[0] a[1] a[2] a[3] a[4]
4 4 6 3 5

因為

j<0所以跳出迴圈

  1. Xa0

現在的序列:

a[0] a[1] a[2] a[3] a[4]
1 4 6 3 5

data movement:4
sum of data movement:7

第三回合

現在的序列:

a[0] a[1] a[2] a[3] a[4]
1 4 6 3 5
  1. 3X
  2. a2>X6

現在的序列:

a[0] a[1] a[2] a[3] a[4]
1 4 6 6 5
  1. a1>X4

現在的序列:

a[0] a[1] a[2] a[3] a[4]
1 4 4 6 5

因為

X>a[j]所以跳出迴圈

  1. Xa1

現在的序列:

a[0] a[1] a[2] a[3] a[4]
1 3 4 6 5

data movement:4
sum of data movement:11

第四回合

現在的序列:

a[0] a[1] a[2] a[3] a[4]
1 3 4 6 5
  1. 5X
  2. a3>X6

現在的序列:

a[0] a[1] a[2] a[3] a[4]
1 3 4 6 6

因為

X>a[j]所以跳出迴圈

  1. Xa3

現在的序列:

a[0] a[1] a[2] a[3] a[4]
1 3 4 5 6

data movement:3
sum of data movement:14

ans:14

請參考投影片25頁與26頁,算出15個有序數列使用Binary Search,平均的比對次數為何?

樹高

log2n+1

A(N)=12n+1(
i=1ki2i1
+
k(n+1)
),where k=log2n+1

i=1ki2i1=2k(k1)+1

A(N)=12n+1(
2k(k1)+1
+k(n+1)),where k=log2n+1

kn=15=log215+1=4

A(15)=12×15+1(24(41)+1+4(15+1))
A(15)=131×(16×3+1+4×16)

A(15)=131×(48+1+64)

A(15)=131×(113)

A(15)=113313.645

Ans:113313.645

第3題:完全平方數

解題思路

第一個小於2147483647的完全平方數是

46340×46340
先判斷是不是在範圍內
找到第一個大於等於
num2
l

然後判斷
l×l
是否等於
num

程式碼

class Solution { public: bool isPerfectSquare(int num) { if(num>46340*46340) { return 0; } int l=1,r=46340,mid; while(l<=r) { mid=(l+r)/2; if(mid*mid>=num) { r=mid-1; } else { l=mid+1; } } return l*l==num; } };

測試輸出輸入的畫面截圖

image

花費時間

7分鐘

完成程度

完全自己解出

第4題

解題思路

二分搜找第一個大於他的值
然後再判斷是不是超出去了

程式碼

class Solution { public: char nextGreatestLetter(vector<char>& letters, char target) { int l=0,r=letters.size()-1,mid; while(l<=r) { mid=(l+r)>>1; if(letters[mid]>target) { r=mid-1; } else { l=mid+1; } } return l>=letters.size()?letters[0]:letters[l]; } };

如果用STL可以秒解:D

class Solution { public: char nextGreatestLetter(vector<char>& letters, char target) { int l = upper_bound(letters.begin(),letters.end(),target) - letters.begin(); return l>=letters.size()?letters[0]:letters[l]; } };

測試輸出輸入的畫面截圖

image

花費時間

4分鐘

完成程度

完全自己解出

第5題

解題思路

二分搜去找mid那點的斜率
分成三個可能

  1. /
    l<=mid<=r
  2. \
    l>=mid>=r
  3. ^
    l<=mid>=r

如果數量不到三個就一個一個看

程式碼

class Solution { public: int peakIndexInMountainArray(vector<int>& arr) { int l=0,r=arr.size()-1,mid; while(r-l>=3) { mid=(l+r)>>1; if(arr[mid+1]>arr[mid]&&arr[mid]>arr[mid-1]) { l=mid+1; } else if(arr[mid-1]>arr[mid]&&arr[mid]>arr[mid+1]) { r=mid-1; } else { return mid; } } int ma=arr[l],in=l; for(int i=l+1;i<=r;i++) { if(arr[i]>ma) { ma=arr[i]; in=i; } } return in; } };

測試輸出輸入的畫面截圖

image

花費時間

14分鐘

完成程度

完全自己解出

第6題

解題思路

跟上次作業求最大值的二分搜概念一樣
把如果是前半段比較大的就把左界拉過去
而右界基本上就是一直縮
加上判斷是不是最尾端再輸出就好

程式碼

class Solution { public: int findMin(vector<int>& nums) { int l=0,r=nums.size()-1,mid; while(l<=r) { mid=(l+r)>>1; if(nums[mid]>=nums[0]) { l=mid+1; } else { r=mid-1; } } return l>=nums.size()?nums[0]:nums[l]; } };

測試輸出輸入的畫面截圖

image

花費時間

8分鐘

完成程度

完全自己解出

第7題

已填