zoukankan      html  css  js  c++  java
  • 两道考研算法设计题- 2010 2013

    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] = { 12345 };
    26     loop(a, 53);
    27     for (int i = 0; i < 5; i++)
    28     cout << a[i] << " ";
    29     return 0;//输出结果:4 5 1 2 3
    30 }
    View Code

    (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 }
    View Code

    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)。

    手里拿着一把锤子,看什么都像钉子,编程界的锤子应该就是算法了吧!
  • 相关阅读:
    反射的概述_反射应用实例
    日期类之SimpleDateFormat
    StringBuffer & StringBuilder
    String与包装类_字节数组_字符数组间的转换
    两种方法k8s安装dashboard组件
    git学习
    Prometheus搭建
    python学习博客
    Python的全局变量和局部变量
    python参数
  • 原文地址:https://www.cnblogs.com/chess/p/4732555.html
Copyright © 2011-2022 走看看