Divide and conquer strategy exercises for algorithm design and analysis (on)

Divide and conquer strategy to solve problem one: search in half

Problem Description

Given that n elements a[0:n-1] have been sorted in ascending order, now we need to find a specific element x among these n elements.

problem analysis

Start searching from the middle of the element, and search for x by halving continuously, and the sub-problems for searching in half are independent of each other.

Algorithm implementation

//折半查找递归实现
int binarySearch(int a[],int left,int right,int x){
    
    
    if(left<=right){
    
    
        int middle = (left + right) / 2;
        if(x == a[middle]) return middle;
        else if(x < a[middle]) return binarySearch(a,left,middle-1,x);
        else return binarySearch(a,middle+1,right,x);
    }
    return -1; //没找到返回-1
}

Divide and conquer strategy to solve the problem two: binary search technology application one

Problem Description

Given a number of integers, ask if the sum of a pair of numbers is equal to the given number.
Input:
4
2 5 1 4
6
Output
1 5
Explanation: If there are multiple pairs of numbers that meet the requirements, output the pair with the smallest number

problem analysis

  • Sort the array from small to large first
  • Use binary search to find a value corresponding to the former
  • Stop searching when found, otherwise continue

Algorithm implementation

//折半查找递归实现
int binarySearch(int a[],int left,int right,int x){
    
    
    if(left<=right){
    
    
        int middle = (left + right) / 2;
        if(x == a[middle]) return middle;
        else if(x < a[middle]) return binarySearch(a,left,middle-1,x);
        else return binarySearch(a,middle+1,right,x);
    }
    return -1; //没找到返回-1
}

void SumNumberSearch(int a[],int length,int sum){
    
    
    for(int i=0;i<length;i++){
    
    
        if(binarySearch(a,i+1,length-1,sum-a[i])){
    
    
            cout<<a[i]<<" "<<sum-a[i];
            break;
        }
    }
}

Divide and conquer strategy to solve problem three: binary search technology application two

Problem Description

Input n numbers, output them from small to large, and output the repeated numbers only once.
Input:
5
2 4 4 5 1
Output:
1 2 4 5

problem analysis

The easiest way is to use set, use the nature of set, here we do not use this method, using binary search technology

  • First sort the array from small to large
  • Starting from the middle number, record the first and last occurrence of the number respectively
  • Analyze the subsequence on the left in the same way
  • Output the number
  • Analyze the right subsequence in the same way

Algorithm implementation

void lineSearch(int a[],int left,int right){
    
    
    int number,middle,l,r,i;
    if(left>right) return;
    middle = (left + right)/2;
    number = a[middle];

    i = middle - 1;
    while(a[i]==number && i>=left) i--;
    l = i;
    i = middle + 1;
    while(a[i]==number && i<=right) i++;
    r = i;

    lineSearch(a,left,l);
    cout<<number<<" ";
    lineSearch(a,r,right);
}

Divide and conquer strategy to solve problem four: mode and multiplicity

Problem Description

For a given multiple number set S consisting of n natural numbers, program to calculate the mode and multiplicity of S

problem analysis

  • Use array storage
  • Sort the array first
  • Record the index of the middle number, the number of occurrences of the middle number, and the position of the first occurrence of the middle number
  • Compare the multiplicity of the intermediate number with the multiplicity of the previous record, if it is greater than the multiplicity of the previous record, update num and sum
  • If the largest multiplicity is less than the number of digits to the right of the middle number, then recursive analysis to the right
  • If the largest multiplicity is less than the number of digits to the left of the middle number, then recursively analyze to the left

Algorithm implementation

#include <iostream>
#include <algorithm>
#define N 100
using namespace std;

int num = 0; //存储众数
int sum = 0; //存储重数
/*
    统计中间数出现的数量
*/
int count(int[],int,int);
/*
    找到中间数第一次出现的位置
*/
int start(int[],int,int);
/*
    找众数和其重数
*/
void modeAndMultiplicity(int[],int,int);

int main()
{
    
    
    int a[N],n;
    cout<<"请输入数组元素数量:";
    cin>>n;
    cout<<"请输入数组元素:";
    for(int i=0;i<n;i++)
        cin>>a[i];
    sort(a,a+n);

    modeAndMultiplicity(a,0,n-1);
    cout<<"众数"<<num<<"的重数为"<<sum<<endl;
    return 0;
}
/*
    统计中间数出现的数量 实现
*/
int count(int a[],int front,int rear){
    
    
    int i = 0; //计数器
    int mid = a[(front+rear)/2];
    for(int j=front;j<=rear;j++){
    
    
        if(a[j] == mid){
    
    
            i++;
        }
    }
    return i;
}

/*
    找到中间数第一次出现的位置 实现
*/
int start(int a[],int front,int rear){
    
    
    int x = 0;
    int mid = a[(front+rear)/2];
    for(int i=front;i <= rear;i++){
    
    
        if(a[i] == mid){
    
    
            x = i;
            break;
        }
    }
    return x;
}

/*
    找众数和其重数 实现
*/
void modeAndMultiplicity(int a[],int front,int rear){
    
    
    int mNum = (front+rear)/2;  //当前中间数的下标
    int mSum = count(a,front,rear); //当前中间数的重数
    int mLeft = start(a,front,rear);    //当前中间数第一次出现的位置

    if(mSum > sum) {
    
        //重数大则替换众数和其重数
        sum = mSum;
        num = a[mNum];
    }

    if(rear-(mLeft+mSum)+1 > sum){
    
       //右边数量大于重数 则向右找
        modeAndMultiplicity(a,mLeft+mSum,rear);
    }

    if(mLeft > sum){
    
        //左边数量大于重数 则向左找
        modeAndMultiplicity(a,front,mLeft-1);
    }
}

Divide and conquer strategy to solve problem five: interval merger

Problem Description

  Given n closed intervals [ai; bi], where i=1,2,...,n. Any two adjacent or intersecting closed intervals can be merged into one closed interval. For example, [1;2] and [2;3] can be combined into [1;3], [1;3] and [2;4] can be combined into [1;4], which is [1;2] and [ 3;4] Can't merge.
  Determine whether these intervals can be finally merged into a closed interval, if so, output the closed interval, otherwise output no.

problem analysis

  • Define interval structure for storage and define comparison function
  • After sorting the input interval groups, divide and conquer on the left and right sides until it is reduced to the merge problem between two small areas
  • If it cannot be combined, the program outputs no and exits directly
  • If possible, merge the results after the end of the divide and conquer to get the final interval

Algorithm implementation

#include <iostream>
#include <algorithm>
//定义区间数量
#define N 100
using namespace std;

//定义区间结构体
struct Interval{
    
    
    int left,right;
};
//定义区间比较函数
bool compareInterval(Interval,Interval);

//区间合并
Interval intervalMerge(Interval[],int,int);

int main()
{
    
    
    Interval interval[N];
    int n;
    cout<<"请输入区间数量:";
    cin>>n;
    for(int i=0;i<n;i++)
        cin>>interval[i].left>>interval[i].right;

    sort(interval,interval+n,compareInterval);

    Interval tempInterval = intervalMerge(interval,0,n-1);

    cout<<tempInterval.left<<" "<<tempInterval.right<<endl;
    return 0;
}

bool compareInterval(Interval mLeft,Interval mRight){
    
    
    if(mLeft.left < mRight.left)
        return true;
    return false;
}

Interval intervalMerge(Interval internal[],int left,int right){
    
    
    if(left == right)
        return internal[left];
    Interval tempInterval1 = intervalMerge(internal,left,(left+right)/2),
             tempInterval2 = intervalMerge(internal,(left+right)/2+1,right);
    if(tempInterval1.right >= tempInterval2.left){
    
      //符合合并条件 进行合并
        Interval tempInterval;
        tempInterval.left = tempInterval1.left;
        tempInterval.right = tempInterval1.right>=tempInterval2.right
                            ?tempInterval1.right
                            :tempInterval2.right;
        return tempInterval;
    }else{
    
      //否则退出
        cout<<"no"<<endl;
        exit(0);
    }
}

Recommended by other articles in this blog

Divide and conquer strategy for algorithm design and analysis

Algorithm design and analysis of recursive algorithm exercises (part 2)

Algorithm design and analysis of recursive algorithm exercises (on)

Digital triangle problem in algorithm design and analysis

Algorithm design and analysis of ZOJ2104- Let the Balloon Rise

Algorithm design and analysis of priority queue and solution ZOJ1167

Guess you like

Origin blog.csdn.net/L333333333/article/details/102531641