本文最后更新于 2025年10月23日 晚上
                  
                
              
            
            
              
                
                2-7 
解:  原问题实际上是要计算以 n 1 , ⋯   , n d n_1,\cdots,n_d n 1  , ⋯ , n d  
P ( x ) = ∏ i = 1 d ( x − n i ) = ∏ i = 1 ⌊ d / 2 ⌋ ( x − n i ) ∏ i = ⌊ d / 2 ⌋ + 1 d ( x − n i ) = P 1 ( x ) P 2 ( x ) \begin{equation*}
	P(x)=\prod_{i=1}^{d}\left(x-n_{i}\right)=\prod_{i=1}^{\lfloor d/2\rfloor}\left(x-n_{i}\right)\prod_{i=\lfloor d/2\rfloor+1}^{d}\left(x-n_{i}\right)=P_{1}\left(x\right)P_{2}\left(x\right)
\end{equation*}
 P ( x ) = i = 1 ∏ d  ( x − n i  ) = i = 1 ∏ ⌊ d /2 ⌋  ( x − n i  ) i = ⌊ d /2 ⌋ + 1 ∏ d  ( x − n i  ) = P 1  ( x ) P 2  ( x )  
记次数为 d d d T ( d ) T(d) T ( d ) 
T ( d ) = { O ( 1 ) d = 1 2 T ( d / 2 ) + O ( d log  d ) d > 1 \begin{equation*}
	T(d)=\begin{cases}
		O(1)&\quad d=1\\
		2T(d/2)+O(d \log d)&\quad d>1		
        \end{cases}
\end{equation*}
 T ( d ) = { O ( 1 ) 2 T ( d /2 ) + O ( d log  d )  d = 1 d > 1   
设 d = 2 t d = 2^t d = 2 t 
T ( d ) = T ( 2 t ) = 2 T ( 2 t − 1 ) + O ( 2 t log  2 t ) = ⋯ = 2 t T ( 1 ) + ∑ k = 1 t 2 t − k O ( 2 k log  2 k ) = O ( d ) + ∑ k = 1 t O ( k ⋅ 2 t ) = O ( d ) + O ( d ) ⋅ ∑ k = 1 t O ( k ) = O ( d ) + O ( d ) ⋅ O ( t 2 ) = O ( d log  2 d ) \begin{align*}
T(d) &= T(2^t) = 2T(2^{t-1}) + O(2^t \log 2^t) \\
	&= \cdots = 2^t T(1) + \sum_{k = 1}^{t} 2^{t-k} O(2^k \log 2^k) \\
	& = O(d) + \sum_{k = 1}^{t} O(k \cdot 2^t) = O(d) + O(d) \cdot \sum_{k = 1}^{t} O(k) \\
	& = O(d) + O(d) \cdot O(t^2) = O(d \log^2 d)
\end{align*}
 T ( d )  = T ( 2 t ) = 2 T ( 2 t − 1 ) + O ( 2 t log  2 t ) = ⋯ = 2 t T ( 1 ) + k = 1 ∑ t  2 t − k O ( 2 k log  2 k ) = O ( d ) + k = 1 ∑ t  O ( k ⋅ 2 t ) = O ( d ) + O ( d ) ⋅ k = 1 ∑ t  O ( k ) = O ( d ) + O ( d ) ⋅ O ( t 2 ) = O ( d log  2 d )  
2-9 
解:  如果数组存在主元素 x x x ∣ S ( x ) ∣ > n / 2 |S(x)| > n/2 ∣ S ( x ) ∣ > n /2 x x x 
寻找数组中位数的算法时间复杂度为 O ( n ) O(n) O ( n ) x 0 x_0 x 0  x 0 x_0 x 0  O ( n ) O(n) O ( n ) O ( n ) O(n) O ( n ) 
2-10 
O(nlogn)算法 
采用分治法。
如果数组存在主元素 x x x ∣ S ( x ) ∣ > n / 2 |S(x)| > n/2 ∣ S ( x ) ∣ > n /2 x x x T ( n ) T(n) T ( n ) n n n H ( n ) H(n) H ( n ) n n n 
对于一个长度为 n n n x 0 x_0 x 0  x 1 , x 2 x_1,x_2 x 1  , x 2  x 0 x_0 x 0  O ( n ) O(n) O ( n ) 
H ( n ) = { O ( 1 ) n ⩽ 4 2 H ( n / 2 ) + O ( n ) n > 4 \begin{equation*}
	H(n)=
	\begin{cases}
		O(1)&\quad n\leqslant4\\
		2H(n/2)+O(n)&\quad n>4
	\end{cases}
\end{equation*}
 H ( n ) = { O ( 1 ) 2 H ( n /2 ) + O ( n )  n ⩽ 4 n > 4   
由主定理,
H ( n ) = O ( n log  n ) \begin{equation*}
	H(n) = O(n \log n)
\end{equation*}
 H ( n ) = O ( n log  n )  
由上面的论述,判断“大众数”是否为主元素,只需验证它在整个数组中出现次数是否大于 n / 2 n/2 n /2 O ( n ) O(n) O ( n ) 
T ( n ) = H ( n ) + O ( n ) = O ( n log  n ) \begin{equation*}
	T(n) = H(n) + O(n) = O(n \log n)
\end{equation*}
 T ( n ) = H ( n ) + O ( n ) = O ( n log  n )  
代码实现 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 #include  <iostream>  #include  <vector>  using  namespace  std;double  findMode (vector<double >& nums, int  left, int  right) if  (left == right) return  nums[left];int  mid = (left + right) / 2 ; double  leftMode = findMode (nums, left, mid); double  rightMode = findMode (nums, mid+1 , right); if  (leftMode == rightMode) return  leftMode;int  leftCnt = 0 , rightCnt = 0 ; for  (int  i = left; i <= right; i++)if  (nums[i] == leftMode)if  (nums[i] == rightMode)if  (leftCnt > rightCnt)return  leftMode;else return  rightMode;class  Solution  {public :double  findMainElement (vector<double >& nums)  int  n = nums.size (); double  res; findMode (nums, 0 , n-1 ); int  cnt = 0 ; for  (int  i = 0 ; i < n; i++)if  (nums[i] == res)if  (cnt > n/2 )return  res;else return  INT_MAX;int  main ()  double > nums = {3 ,2 ,1 ,2 ,3 ,2 ,3 };"Main element: "  << s.findMainElement (nums) << endl;return  0 ;       
O(n)算法 
设数组为 A 0 [ 0 : n − 1 ] A_0 [0:n-1] A 0  [ 0 : n − 1 ] 
A 0 [ 0 ] ↔ A 0 [ n − 1 ] , A 0 [ 1 ] ↔ A 0 [ n − 2 ] , ⋯   , A 0 [ ( ⌊ n / 2 ⌋ ) / 2 ] ↔ A 0 [ ( ⌊ n / 2 ⌋ + 1 ) / 2 ] A_0 [0] \leftrightarrow A_0 [n-1], A_0 [1] \leftrightarrow A_0 [n-2], \cdots , A_0 [(\lfloor n/2\rfloor)/2] \leftrightarrow A_0 [(\lfloor n/2\rfloor+1)/2]
 A 0  [ 0 ] ↔ A 0  [ n − 1 ] , A 0  [ 1 ] ↔ A 0  [ n − 2 ] , ⋯ , A 0  [(⌊ n /2 ⌋) /2 ] ↔ A 0  [(⌊ n /2 ⌋ + 1 ) /2 ] 
如果 n n n A 0 [ ( n + 1 ) / 2 ] A_0 [(n+1)/2] A 0  [( n + 1 ) /2 ] 
然后对每一对二元组进行比较,判断二者是否相等:如果相等,则将其中一个写入数组 A 1 A_1 A 1  
设 T ( n ) T(n) T ( n ) n n n 
T ( n ) ≤ { O ( 1 ) n ⩽ 2 2 T ( n / 2 ) + 1 n > 2 \begin{equation*}
	T(n) \leq \begin{cases}
		O(1)&\quad n\leqslant2\\
		2T(n/2) + 1&\quad n>2
	\end{cases}
\end{equation*}
 T ( n ) ≤ { O ( 1 ) 2 T ( n /2 ) + 1  n ⩽ 2 n > 2   
设 n = 2 t n = 2^t n = 2 t 
T ( n ) ≤ 2 T ( n / 2 ) + 1 ≤ 4 T ( n / 4 ) + 2 + 1 ≤ ⋯ ≤ 2 t T ( 1 ) + ∑ k = 1 t − 1 2 k = O ( 2 t ) + 2 t − 1 = O ( 2 t ) = O ( n ) \begin{align*}
	T(n) &\leq 2T(n/2) + 1 \leq 4T(n/4) + 2 + 1 \\
		&\leq \cdots \leq 2^t T(1) + \sum_{k = 1}^{t-1} 2^k \\
		&= O(2^t) + 2^t - 1 = O(2^t) \\
		&= O(n)
\end{align*}
 T ( n )  ≤ 2 T ( n /2 ) + 1 ≤ 4 T ( n /4 ) + 2 + 1 ≤ ⋯ ≤ 2 t T ( 1 ) + k = 1 ∑ t − 1  2 k = O ( 2 t ) + 2 t − 1 = O ( 2 t ) = O ( n )  
因此上述算法是线性时间的。
代码实现 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 #include  <iostream>  #include  <vector>  using  namespace  std;class  Solution  {public :double  findMainElement (vector<double >& nums)  int  n = nums.size (); vector<double > arr (nums)  ; int  cnt = n; double  res; while  (cnt > 1 )int  cnt_temp = 0 ; for  (int  i = 0 ; i < cnt / 2 ; i++)if  (arr[i] == arr[cnt-1 -i]) int  temp = arr[i];if  (cnt % 2  != 0 )2  + 1 ];if  (cnt == 1 ) 0 ];else  return  INT_MAX; 0 ; for  (int  i = 0 ; i < n; i++)if  (nums[i] == res)if  (cnt > n/2 )return  res;else return  INT_MAX;int  main ()  double > nums = {1 ,3 ,1 ,2 ,2 ,1 };"Main element: "  << s.findMainElement (nums) << endl;return  0 ;       
2-28 
采用递归方法。
设 T ( n ) T(n) T ( n ) 2 n 2n 2 n X [ l e f t 1 , r i g h t 1 ] , Y [ l e f t 2 , r i g h t 2 ] X[left1,right1],Y[left2,right2] X [ l e f t 1 , r i g h t 1 ] , Y [ l e f t 2 , r i g h t 2 ] x , y x,y x , y m 1 = ⌊ ( l e f t 1 + r i g h t 1 ) / 2 ⌋ , ⌊ m 2 = ( l e f t 2 + r i g h t 2 ) / 2 ⌋ m1 = \lfloor (left1 + right1) / 2\rfloor , \lfloor m2 = (left2 + right2) / 2 \rfloor m 1 = ⌊( l e f t 1 + r i g h t 1 ) /2 ⌋ , ⌊ m 2 = ( l e f t 2 + r i g h t 2 ) /2 ⌋ x = y x = y x = y x x x 
否则,不妨设 x < y x < y x < y x > y x > y x > y 
y y y X [ l e f t 1 , r i g h t 1 ] , Y [ l e f t 2 , r i g h t 2 ] X[left1,right1],Y[left2,right2] X [ l e f t 1 , r i g h t 1 ] , Y [ l e f t 2 , r i g h t 2 ] x x x X [ l e f t 1 , r i g h t 1 ] , Y [ l e f t 2 , r i g h t 2 ] X[left1,right1],Y[left2,right2] X [ l e f t 1 , r i g h t 1 ] , Y [ l e f t 2 , r i g h t 2 ] X [ m 1 + 1 , r i g h t 1 ] , Y [ l e f t 2 , m 2 ] X[m1+1,right1], Y[left2,m2] X [ m 1 + 1 , r i g h t 1 ] , Y [ l e f t 2 , m 2 ] Y [ l e f t 2 , m 2 − 1 ] Y[left2,m2-1] Y [ l e f t 2 , m 2 − 1 ] 
上述过程中,查找了 X 、 Y X、Y X 、 Y O ( 1 ) O(1) O ( 1 ) 
\begin{equation*}
	T(2n) = T(n) + T(n) = 2T(n/2) + O(1)
		\begin{cases}
			O(1)&\quad n=1\\
			T(n/2)+O(1)&\quad n>1
		\end{cases}
\end{equation*}
令 $n = 2^t$,有
\begin{align*}
	T(n) &= T(2^t) = T(2^{t-1}) + O(1) + = \cdots \\
		&= T(1) + \sum_{k = 1}^{t} O(1) = O(1) + O(t)\\
		&= O(\log n)
\end{align*}
代码 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 #include  <iostream>  #include  <vector>  using  namespace  std;double  Median (vector<double >& X, int  left, int  right)  int  n = right - left + 1 ;if  (n % 2  == 0 ) return  (X[left + n/2  - 1 ] + X[left + n/2 ]) / 2.0 ;else  return  X[left + n/2 ];class  Solution {public :double  findMedian (vector<double >& X, vector<double >& Y, int  left1, int  right1, int  left2, int  right2)  int  m1 = (left1 + right1) / 2 ; int  m2 = (left2 + right2) / 2 ;int  n = right1 - left1 + 1 ; if  (n == 1 )return  (X[left1] + Y[left2]) / 2.0 ;double  x = Median (X, left1, right1); double  y = Median (Y, left2, right2); if  (x == y)return  x;else  if  (x < y)if  (n % 2  == 0 ) return  findMedian (X, Y, m1+1 , right1, left2, m2);else return  findMedian (X, Y, m1+1 , right1, left2, m2-1 );else if  (n % 2  == 0 ) return  findMedian (X, Y, left1, m1, m2+1 , right2);else return  findMedian (X, Y, left1, m1-1 , m2+1 , right2);int  main ()  double > X = {1 , 2 , 4 , 4 , 6 };double > Y = {2 , 2 , 3 , 5 , 5 };int  n = X.size ();double  res = s.findMedian (X, Y, 0 , n-1 , 0 , n-1 );return  0 ;