算法面试题解答(一)

1. 在一个数组中找出出现次数超过n/2的元素

第一次看到这个题目是在《编程之美》上,书上给的算法是,每次从数组中删除两个不一样的元素,那最后剩下的就是出现次数超过n/2的元素,但是这种很直观的办法要么就是破坏原来的数组,要么将原数组复制一份,这样都不好,有没有空间需求是O(0),而且不破坏原数组的方法呢? 下面就是这样的一种方法,用一个计数器统计出现次数,如果发现一个跟现在保存的值不一样的,就将其减一,如果计数变成0,那么就需要更新这个值,其思想跟之前的类似,但是它的空间需求是O(0)的。下面是代码:

static void Main(string[] args)
        {
            int[] list = new int[] { 1, 2, 3, 2, 2, 3, 4, 2, 3, 2, 1, 2, 2, 4, 2, 1, 2, 1 };
            //   int[] list = new int[] {2,1,2,1,2};

            int count = 1;
            int majorityElement = list[0];
            for (int index = 1; index < list.Length; index++)
            {

                if (majorityElement != list[index])
                {
                    if (count == 0) //之前出现的次数都因为有同等数量的不相同元素而被抵消,这时考虑更换majorityElement的值
                    {
                        majorityElement = list[index];
                        count++;
                    }
                    else // 碰到相异元素,抵消一次
                    {
                        count--;
                    }
                }
                else //碰到相同元素,增加一次
                {
                    count++;
                }
                //do see intermediate output enable following line
               
//System.out.println(list[index]+": " + count);

            }
            if (count > 0)
                Console.WriteLine("Majority Element: " + majorityElement);
            else
                Console.WriteLine("no any element appear over n/2 times");
        }

2. String Permutation

Printing all permutations of a string is a very common interview question. We'll discuss this problem and some interesting variations of it. The original problem of string permutation says, "print all permutations of a string". As an example, if the string is "abc" there are 6 permutations {abc, acb, bac, bca, cab, cba}. Assume that string contains no duplicate elements. 代码如下:

void stringpermutate(char *src, int index, int totallen)
{
    if(index>totallen-1)
        return;
    if(index == (totallen-1))
        cout<<src<<i++<<endl;

    int i = 0;
    for(i = index;i<totallen;i++)
    {
        char t = ' ';
        if(index != i)
        {
            std::swap(src[index],src[i]);
            t = src[index];
            src[index] = src[i];
            src[i] = t;
        }
        stringpermutate(src,index+1,totallen);
        if(index != i)
        {
            t = src[index];
            src[index] = src[i];
            src[i] = t;
        }
    }
}

3. Search An Element In A Sorted Rotated Array

这是用来考察二叉搜索的一道好题,基本思路是找到rotate发生的点,将数组分为两部分,然后分别在这两部分中进行二叉搜索,代码如下:

int findPivot(int *arr, int beginIndex, int endIndex)
{
    if(endIndex >= beginIndex)
    {
        int mid = (endIndex-beginIndex)/2;
        if(arr[mid] >arr[mid+1])
            return mid;
        else if(arr[mid] > arr[endIndex])
        {   
            return findPivot(arr,mid+1, endIndex);
        }
        else 
        {
            return findPivot(arr,beginIndex, mid-1);
        }
    }   
    return -1;
}

int binarySearch(int *arr, int beginIndex, int endIndex, int pattern)
{
    if(endIndex >= beginIndex) //二叉搜索很简单,但是这一步检查很重要,因为在搜索递归的过程中,beginIndex和endIndex的差距越来越小,直至超越就是停止的时候
    {
        int mid = (endIndex-beginIndex)/2;
        if(arr[mid] == pattern)
            return mid;
        else if(arr[mid]>pattern)
        {
            return binarySearch(arr, beginIndex, mid-1, pattern);//endIndex在变小
        }else
        {
            return binarySearch(arr,  mid+1, endIndex, pattern);//beginIndex在变大
        }
    }
    return -1;
}

int RotatedBinarySearch(int *arr, int len, int pattern)
{
    int pivot = findPivot(arr, 0, len-1);
    if(pivot == -1)
    {
        return binarySearch(arr,0,len-1,pattern);
    }
    else
    {
        if(arr[pivot]==pattern ) // return value of findPivot is >=0, here we only need consider special case :0
            return pivot;
        if(arr[len-1]<pattern)
            return binarySearch(arr,0,pivot-1, pattern);
        else
            return binarySearch(arr,pivot,len-1, pattern);
    }
}

4. Rotate Array By K Elements

STL中有rotate的实现,其中包括3种方法,每种方法对迭代器的要求是不一样的,这里分别实现一下,尤其复习一下GCD的应用。

原文地址:https://www.cnblogs.com/whyandinside/p/2767943.html