1.已知数组a前半部分a[0,mid - 1],后半部分a[mid,num-1],现前半部分和后半部分均已排好序。要求:实现a数组的从小到大排序。空间复杂度为O(1).

void MergeSort(int *v, const int len, const int mid)  
{    
    int i, temp;  
    int left = 0, right = mid;  
  
    while (left < right && right < len)  
    {  
        while (v[left] < v[right]) {  
            ++ left;  
        }   
  
        temp = v[right];  
        for(i = right; i > left ; -- i) {  
            v[i] = v[i-1];  
        }  
        v[left] = temp;  
  
        //move the current right postion  
        ++ right;     
    }  
  
}  
//int arry[]={1,3,5,7,9,3,4,6,8};  
//int arry[]={1,3,5,7,9,7,8,9,9,11};  
//int arry[] = {0,2,4,6,8,8,9,9,1000,1,3,5,7,10,11,12,14,16,18,20,21,23,25,45,68};     
  int v[] = {100,1,3,5,7,10,11,12,14,16,18,20,21,23,25,45,68};

2.给一个字符串和一个字符集,求该字符串包含字符集的子串

给出一个字符串,及一个字符集,求该字符串包含所有字符集的最短子串

思路:每次找到一个在字符集中出现的字符,都判断该字符是否是第一次出现,如果是第一次出现,直接记录其下标,如果不是第一次出现,看下它是否和index指向的那个字符是否为相同字符,如果是相同字符,需要更新index找到它后面的第一个已经出现的字符,如果不是index的指向,只需要更新他的下标即可,index中保留的始终是满足都出现的最大下标,这样使得找到的长度是最短的。

时间复杂度O(n)

#include <iostream>
using namespace std;
const int N=128;
const int INF=10000;
const int MAXLEN=100;
//找到所有已经出现的最小下标
int getMinIdx(char *s)
{
    int rs=-1;
    for(int i=0;i<N;i++)
    {
        if(s[i]>=0)
        {
            if(rs == -1)
                rs=s[i];
            else if(rs>s[i])
                rs=s[i];
        }
    }
    return rs;
}
void findMinSubStr(char *str,char *set)
{
    int i,minIdx,subIndex,minLen,num;
    minIdx=-1;
    minLen=INF;
    subIndex=-1;
    num=0;
    char idx[N],result[MAXLEN];
    for(i=0;i<N;i++)
        idx[i]=-2; //初始化符号及标记数组
    for(i=0;'\0' != set[i];i++)
    {
        idx[set[i]]=-1;
        num++; //统计字符集大小
    }
    cout<<num<<endl;
    for(i=0;'\0' != str[i];i++)
    {
        if(idx[str[i]] > -2)//判断字符串中的字符是否出现在字符集中
        {
            if(-1 == idx[str[i]]) //判断是否第一次出现
            {
                idx[str[i]]=i;
                num--;
                if(-1 == minIdx)
                    minIdx=i; //minIdx指向字串的开始下标
            }
            else if(minIdx == idx[str[i]]) 
//如果当前字符与子串第一个字符相同则更新子串第一个字符为下一个已经出现的字符
//看下它是否和index指向的那个字符是否为相同字符,如果是相同字符,需要更新index找到它后面的第一个已经出现的字符
            {
                idx[str[i]]=i;
                minIdx=getMinIdx(idx);//返回所有已经出现字符的最小下标
            }
            else //若都不是直接更新下标到idx
            {
                idx[str[i]]=i;
            }
        }
        if(!num)
        {
            if(minLen > (i-minIdx+1))
            {
                subIndex=minIdx;
                minLen=i-minIdx+1;
            }
        }
        cout<<subIndex<<' '<<minIdx<<' '<<minLen<<endl;
    }
    for(i=0;i<minLen;i++)
    {
        result[i]=str[i+subIndex];
    }
    result[i]='\0';
    cout<<"包含字符集中所有字符的最短子串为:";
    cout<<result<<endl;
}
int main()
{
    char str[MAXLEN],set[MAXLEN];
    memset(str,'\0',sizeof(MAXLEN));
    memset(set,'\0',sizeof(MAXLEN));
    cout<<"输入字符串和字符集:"<<endl;
    cin>>str>>set;
    findMinSubStr(str,set);
    return 0;
}

二分法的递归与非递归

递归:

void Search(int p[],int low,int height,int key)  
{  
    int middle=(low+height)/2;  
    if(low>height)  
    {  
        printf("没有该数!");  
        return;  
    }  
    if(p[middle]==key)  
    {  
        printf("%d\n",middle);  
        return;  
    }  
    else if(p[middle]>key)  
    {  
         Search(p,low,middle-1,key);  
    }  
    else if(p[middle]<key)  
    {  
         Search(p,middle+1,height,key);  
    }  
} 
int main()  
{  
    int p[5]={1,2,3,4,5};  
    Search(p,0,4,4);  
    return 0;  
}

非递归:

int Search(int* arr, int size,int key)
{
	if (arr == NULL || size <= 0)
		return;
	int mid = 0;
	int begin = 0;
	int end = size - 1;
	while (begin <= end)
	{
		mid = begin + ((end - begin) >> 2);
		if (arr[mid] == key)
			return mid;
		else if (arr[mid] > key)
		{
			end = mid - 1;
		}
		else
		{
			begin = mid + 1;
		}
	}
	return -1;
}
题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增的排序的数组的一个旋转,输出旋转数组的最小元素。例如输入{1,2,3,4,5}的一个旋转为{3,4,5,1,2},该数组的最小值为1。
public class Solution {
    public int minNumberInRotateArray(int [] array) {
        int low = 0 ; int high = array.length - 1;   
        while(low < high){
            int mid = low + (high - low) / 2;        
            if(array[mid] > array[high]){
                low = mid + 1;
            }else if(array[mid] == array[high]){
                high = high - 1;
            }else{
                high = mid;
            }   
        }
        return array[low];
    }
}