面试总结(二)

 

1.对称子字符串的最大长度

题目叙述:

     输入一个字符串,输出该字符串中对称的子字符串的最大长度。比如输入字符串“google”,由于该字符串里最长的对称子字符串是“goog”,因此输出4。

     提示:可能很多人都写过判断一个字符串是不是对称的函数,这个题目可以看成是该函数的加强版。

第一种方法:此方法比较容易想到,但是时间复杂度比较高O(n^3)。

//判断字符串是否对称
int IsDuiChen(char *pstart,char* pend)
{
    int flag = 1;
    while (pstart < pend)
    {
        if (*pstart!=*pend)
        {
            flag = 0;
            break;
        }
        pstart++;
        pend--;
    }
    return flag;
} 

//对称字符串的最大长度  此算法时间复杂度为O(n^3)
int MaxLenOfDuiChen(char *str)
{
    int i,j = 0,MaxLen = 1;
    int len = strlen(str);
    for (i = 0;i < len;i++)
    {
        for (j = i+1;j < len;j++)
        {
            if (IsDuiChen((str+i),(str+j))== 1)
            {
                if (MaxLen < j-i+1)
                {
                    MaxLen = j-i+1;
                }
            }
        }
    }
    return MaxLen;
}
View Code

第二种方法:此方法稍微复杂,但是时间复杂度较低O(n^2)。

//对称字符串的最大长度  此算法时间复杂度为O(n^2)
int LongestOfDuiChen(char* str)
{
    int len = strlen(str),maxLen = 1;
    int newLen;
    int i=0;
    char* left = NULL,*right = NULL;
    char* pchar = str;
    if (str == NULL)
    {
        return;
    }
    while (i<len-1)
    {
        //子字符串为奇数
        left = pchar-1;
        right = pchar+1;
        newLen = 1;
        while (left>=str && right<=str+len-1 && *left==*right)
        {
            left--;
            right++;
            newLen+=2;
        }
        if (newLen>maxLen)
        {
            maxLen = newLen;
        }
        //子字符串为偶数
        left = pchar;
        right = pchar+1;
        newLen = 0;
        while (left>=str && right<=str+len-1 && *left==*right)
        {
            left--;
            right++;
            newLen+=2;
        }
        if (newLen>maxLen)
        {
            maxLen = newLen;
        }

        pchar++;
        i++;
    }
    return maxLen;
}
View Code

2.编程判断俩个链表是否相交

题目叙述:

      给出俩个单向链表的头指针,比如h1,h2,判断这俩个链表是否相交。为了简化问题,我们假设俩个链表均不带环。

问题扩展:

  • 如果链表可能有环列?
  • 如果需要求出俩个链表相交的第一个节点列?

无环的情况下:只需分别求出两个链表的最后一个节点判断是否相等就可以了。

//编程判断俩个链表是否相交(无环)
int IsCommonOfLinklists(Node* node1,Node* node2)
{
    int IsCommon = 0;
    Node* p1= node1,*p2 = node2;
    if (p1 == NULL || p2 == NULL)
    {
        IsCommon =0;
    }
    while (p1->next !=NULL)
    {
        p1 = p1->next;
    }
    while (p2->next !=NULL)
    {
        p2 = p2->next;
    }
    if (p1 == p2)
        IsCommon = 1;
    return IsCommon;
}
View Code


可能有环的情况下:如果有环返回链表环的第一个节点。然后将得到的节点指针作为参数传入另一个链表去判断是否在其上

/编程判断俩个链表是否相交(可能有环)
//如果有环返回环的第一个节点
Node* FindFirstCircleNode(Node* Head)
{
    int flag = 0;
    Node *slow = Head,*fast = Head;
    if (Head != NULL)
    {
        return NULL;
    }
    while (fast!=NULL &&fast->next !=NULL)
    {
        slow = slow->next;
        fast = fast->next->next;
        if (slow == fast)
        {
            flag = 1;
            break;
        }
    }
    if (flag == 1)
        slow = Head;
    else
        return NULL;
    while(fast != slow)
    {
        slow = slow->next;
        fast = fast->next;
    }

    return fast;
}
View Code


3.在O(1)时间内删除单链表结点

题目叙述:给定单链表的一个结点的指针,同时该结点不是尾结点,此外没有指向其它任何结点的指针,请在O(1)时间内删除该结点。

此题摘自<微软面试100题>中

//在O(1)时间内删除单链表结点
void DeleteNode(Node* node)
{
    Node *Tem ,*p = node;
    if (node == NULL)
    {
        return;
    }
    Tem = node->next;
    p->c = Tem->c;
    p->next = Tem->next;
    free(Tem);
    Tem = NULL;
}
View Code

 

4.字符个数的统计

 题目叙述:

      char *str = "AbcABca"; 写出一个函数,查找出每个字符的个数,区分大小写,要求时间复杂度是n(提示用ASCII码)

//字符个数的统计
void statisticsNumsOfChar(char* str)
{
    int i,j,len = strlen(str);
    int a[256] = {0};

    for (i = 0;i < len;i++)
    {
        a[*(str+i)] ++;
    }
    for (j = 0;j < 256;j++)
    {
        if(a[j] > 0)
        {
            printf("%-2c%d\n",(char)j,a[j]);
        }
    }

}
View Code

5.字符串通配符匹配问题

题目叙述:在一篇英文文章中查找指定的人名,人名使用二十六个英文字母(可以是大写或小写)、空格以及两个通配符组成(*、?),通配符“*”表示零个或多个任意字母,通配符“?”表示一个任意字母。

如:“J* Smi??” 可以匹配“John Smith” .

请用C语言实现如下函数: void scan(const char* pszText, const char* pszName); 注:pszText为整个文章字符,pszName为要求匹配的英文名。 请完成些函数实现输出所有匹配的英文名,除了printf外,不能用第三方的库函数等。

该算法摘自:微软、Google等公司的面试题及解答、第161-170题

//字符串匹配问题
int scan(const char* text, const char* pattern)  
{  
    const char *p = pattern;    // 记录初始位置,以便patten匹配一半失败可返回原位   
    if (*pattern == 0) return 1;    // 匹配成功条件   
    if (*text == 0) return 0;    // 匹配失败条件   
      
    if (*pattern != '*' && *pattern != '?')  
    {  
        if (*text != *pattern)    //如果匹配不成功     
            return scan(text+1, pattern);    //text++,寻找下一个匹配   
    }  
      
    if (*pattern == '?')  
    {  
        if (!((*text>='a' && *text<='z')||(*text>='A' && *text<='Z')))    // 通配符'?'匹配失败   
        {  
            pattern = p;    // 还原pattern初始位置   
            return scan(text+1, pattern);    //text++,寻找下一个匹配   
        }  
        else                    // 通配符'?'匹配成功   
        {  
            return scan(text+1, pattern + 1);  //双双后移,++   
        }  
    }  
    return scan(text, pattern+1);    // 能走到这里,一定是在匹配通配符'*'了   
}  

 

posted on 2014-08-28 15:39  DLMUCAI付  阅读(245)  评论(0编辑  收藏  举报