【算法集训之线性表篇】Day 04

题目一

从有序顺序表中删除所有其值重复的元素,使所有元素的值都不相同。

分析

思路一

  1. 首先,在有序顺序表中,所有值重复的元素相邻。为此,我们只需顺序访问顺序表中的元素,并查找出值重复的元素并删除。
  2. 因此,我们可以设置二维变量数组buzz记录重复元素个数,遍历到当前元素时,将当前元素与后一元素比较,若相同,buzz值加一。若不同,加入下一元素的重复个数。
  3. 最后,再将buzz数组中的元素读入原顺序表,即可完成题目要求。此算法时间复杂度为O(n),空间复杂度为O(n)。

思路二

  1. 根据有序顺序表的特性,我们可以考虑利用直接插入排序的思想,将第零个元素作为不重复元素,后续元素与前面元素比较,若值不同,则插入顺序表,并更新不重复元素比较基准值为当前元素。时间复杂度为O(n),空间复杂度为O(1)。

代码实现

下面仅实现思路二的代码

int LinearList::Question_06()
{
    
    
    if(arr.length <= 0)
        return -1;
    int i = 0,j = 1;
    for(i = 0,j= 1;j < arr.length;j ++)
    {
    
    
        if(arr.data[j] != arr.data[i])
            arr.data[++i] = arr.data[j];
    }
    arr.length = i + 1;
    return 0;
}

效果

在这里插入图片描述

题目二

线性表(a1,a2,a3…,an)中的元素递增有序且按顺序存储于计算机内。要求设计一个算法,完成用最少时间在表中查找数值为x的元素,若找到,则将其与后继元素位置互换。反之,则将其插入表中使表中元素仍然递增有序。

分析

  1. 题目涉及到元素查找且要求时间最短,可以考虑折半查找的算法思想将线性表一分为二,将key值与中间元素比较。若相等,则查找成功。若不等,则该元素必然在线性表的左区间或者右区间中。再重复上述步骤,当区间长度等于1(查找失败)或者查找成功,则推出算法。
  2. 若查找成功,则将该元素与后一元素互换。若查找失败,则在刚刚最后查找位置插入key值,即可完成题目要求。时间复杂度为O(log2n),空间复杂度为O(1)。

代码实现

Array LinearList::Question_09(int x)
{
    
    
    int key = x;
    //折半查找key
    int left = 0,right = arr.length-1,mid = 0;
    while(left <= right)
    {
    
    
        mid = (left+right)/2;
        cout<<"mid: "<<mid<<endl;
        if(arr.data[mid] == key)//若查找成功
        {
    
    
            int temp = arr.data[mid];
            arr.data[mid] = arr.data[mid+1];
            arr.data[mid+1] = temp;
            return arr;
        }
        if(arr.data[mid] > key)//key可能在左半区间
        {
    
    
            right = mid-1;
        }
        else if(arr.data[mid] < key)//key可能在右半区间
        {
    
    
            left = mid+1;
        }
    }

    //查找失败
    arr.length ++;
    for(int i = arr.length-1;i > left;i --)
    {
    
    
        arr.data[i] = arr.data[i-1];
    }
    arr.data[left] = key;
    return arr;
}

效果

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/wddkxg/article/details/131605858