2010:
设将n(n>1)个整数存放到一维数组R中。试设计一个在时间和空间两方面都尽可能高效的算法,将R中保存的序列循环左移P(0<P<n)个位置,即将R中的数据由(x0,x1,…,xn-1)变换为(xp,xp+1,…,xn-1,x0,x1,…,xp-1)。要求:
(1)给出算法的基本设计思想。
(2)根据设计思想,采用C或C++或JAVA语言描述算法,关键之处给出注释。
(3)说明设计算法的时间复杂度和空间复杂度。
【解析】:
(1)前P个数依次进队,while(i<n-p) A[i]=A[i+p];P个数依次出队,进入数组末尾;
或者,使用数学里的分析方法:
循环左移p个位置,也就是将数组分为2部分,前一部分从0到p-1,后一部分从p到n-1,将数组的前一部分跟后一部分进行了交换。
首先逆序前一部分,然后逆序后一部分,左后整个逆序。以此实现循环左移:酷酷的!
其数学原理:(a-1b-1)-1=ba
代码如下:
1 #include<iostream> 2 #include<string> 3 using namespace std; 4 5 void reverse(int a[],int begin,int end) 6 { 7 int i = begin, j = end,temp; 8 while (i < j) 9 { 10 a[i] = a[j]; 11 a[j] = temp; 12 ++i; 13 --j; 14 } 15 } 16 void loop(int *a, int len, int p) 17 { 18 reverse(a, 0, p - 1); 19 reverse(a, p, len-1); 20 reverse(a, 0, len-1); 21 } 22 23 int main() 24 { 25 int a[5] = { 1, 2, 3, 4, 5 }; 26 loop(a, 5, 3); 27 for (int i = 0; i < 5; i++) 28 cout << a[i] << " "; 29 return 0;//输出结果:4 5 1 2 3 30 }
(3)时间复杂度O(N),空间复杂度O(1)。
2013:
【解析:】
(1)算法思想:
首先保存整数序列的第一个数到res中,并计数count=1,然后从后往前(从前往后也一样)遍历,若是第二个数等于res,则count自增,否则count自减,若是count等于0,则res保存整数序列中将要遍历的下一个整数。
其次,我们来进行验证,遍历一遍整数序列,若是整数等于上一步中的res,则count自增,否则不做处理;如果最后count大于n/2,则说明res就是主元素,否则返回-1,说明主元素不存在。
(2)c++实现的代码如下:
1 #include<iostream> 2 using namespace std; 3 int getNum(int *arr, int len) 4 { 5 int res=arr[0],count=1; 6 while (len > 0) 7 { 8 if (arr[len] == res) 9 count++; 10 else 11 { 12 --count; 13 if (count == 0) 14 res = arr[len - 1]; 15 } 16 len--; 17 } 18 return res; 19 } 20 int verify(int *arr, int len) 21 { 22 int count = 0; 23 int num = getNum(arr, len); 24 for (int i = 0; i < len;i++) 25 if (num == arr[i]) 26 ++count; 27 if (count>len / 2) 28 return num; 29 else 30 return -1; 31 } 32 int main() 33 { 34 int arr[] = { 0,5,5,3,5,7,5,5 }; 35 int result = verify(arr, 8); 36 cout << result << endl; 37 return 0; 38 }
update-2015-8-20:网上一段更简洁的代码:
1 class Solution { 2 public: 3 int majorityElement(vector<int> &num) { 4 int nTimes = 0; 5 int candidate = 0; 6 for(int i = 0; i < num.size(); i ++) 7 { 8 if(nTimes == 0) 9 { 10 candidate = num[i]; 11 nTimes = 1; 12 } 13 else 14 { 15 if(candidate == num[i]) 16 nTimes ++; 17 else 18 nTimes --; 19 } 20 } 21 return candidate; 22 } 23 };
(3)数组遍历了两次,但是每次都是O(n),空间上只使用了几个辅助变量,所以时间复杂度为O(n),空间复杂度为O(1)。