【剑指offer】第四十九题(丑数) 和 第五十题(第一个只出现一次的字符)

第四十九题:丑数

题目:

我们把只包含因子 2、3、5 的数称作丑数。求按从小到大的顺序的第 1500 个丑数。例如,6、8都是丑数,但 14 不是,因为它包含因子 7.习惯上我们把 1 当做第一个丑数。

解题程序:

#include<iostream>
#include<stdio.h>
using namespace std;

// 解法一:逐个判断每个整数是不是抽数的解法,直观但不够高效

bool IsUgly(int number)
{
    while( number % 2 == 0 )
        number /= 2;

    while( number % 3 == 0 )
        number /= 3;

    while( number % 5 == 0 )
        number /= 5;

    return (number == 1) ? true:false;
}

int GetUglyNumber(int index)
{
    if( index <= 0 )    
    {
        return 0;
    }
    
    int number = 0;
    int uglyFound = 0;

    while(uglyFound < index)
    {
       ++number; 
        if( IsUgly(number) )
        {
            ++uglyFound;
        }
    }
    
    return number;
}

// 解法二:创建数组保存已经找到的丑数,用时间换空间

// 获取三个数中最小的数字
int Min(int num1,int num2,int num3)
{
    int min = num1 < num2 ? num1:num2;
    min = min < num3 ? min:num3;
    return min;
}

int GetUglyNumber1(int index)
{
    if(index <= 0)
        return 0;

    int *pUglyNumbers = new int[index];
    for(int i=0;i<index;i++)
    {
        pUglyNumbers[i] = 0;
    }
    pUglyNumbers[0] = 1;
    
    int nextUglyIndex = 1;

    int *pMultiply2 = pUglyNumbers;
    int *pMultiply3 = pUglyNumbers;
    int *pMultiply5 = pUglyNumbers;

    while(nextUglyIndex < index)
    {
       int min = Min(*pMultiply2*2,*pMultiply3*3,*pMultiply5*5); 

        pUglyNumbers[nextUglyIndex] = min;
    
        //printf("*pMultiply2 = %d,*pMultiply3 = %d,*pMultiply5 = %d\n",*pMultiply2,*pMultiply3,*pMultiply5);
        //printf("min = %d,pUglyNumbers[nextUglyIndex] = %d\n",min,pUglyNumbers[nextUglyIndex]);
        while( *pMultiply2 * 2 <= pUglyNumbers[nextUglyIndex] )
            ++pMultiply2;

        while( *pMultiply3*3 <= pUglyNumbers[nextUglyIndex] )
            ++pMultiply3;
        
        while( *pMultiply5*5 <= pUglyNumbers[nextUglyIndex] )
            ++pMultiply5;

        ++nextUglyIndex;
    }

    int ugly = pUglyNumbers[nextUglyIndex-1];
    delete  []pUglyNumbers;
    pUglyNumbers = NULL;
    return ugly;
}

// 测试用例

void test()
{
    int index;
    printf("请输入 index: \n");
    scanf("%d",&index);

    printf("解法一:\n");
    int ret  = GetUglyNumber(index);
    if( ret )
        printf("第 %d 个丑数是: %d\n",index,ret);
    else
        printf("程序出错!\n");

    printf("解法一:\n");
    
    ret  = GetUglyNumber1(index);
    if( ret )
        printf("第 %d 个丑数是: %d\n",index,ret);
    else
        printf("程序出错!\n");


}


int main(void)
{
    test();
    return 0;
}


第五十题:第一个只出现一次的字符

题目一:字符串中第一个只出现一次的字符

在字符串中找出第一个只出现一次的字符。如输入“abaccdeff”,则输出 'b'。

解题程序:

#include<iostream>
#include<stdio.h>
using namespace std;

char FirstNotRepeartingChar(char *str)
{
    if( str == NULL )
        return '\0';
    
    const int tableSize = 256;
    unsigned int hashTable[tableSize];

    for(int i=0;i<tableSize;i++)
    {
       hashTable[i]  = 0;
    }
    
    char *pHashKey = str;
    
    while( *pHashKey != '\0' )
    {
        printf("*pHashKey = %d\n",*pHashKey);
        hashTable[*pHashKey++]++;
    }

    pHashKey = str;

    while(*pHashKey != '\0')
    {
       if(hashTable[*pHashKey] == 1) 
            return *pHashKey;            
        pHashKey++;
    }
    
    return '\0';
}

// 测试用例

void test()
{
    char str[100] = "";
    printf("请输入字符串:\n");
    scanf("%s",str);
    
    char c = FirstNotRepeartingChar(str);
    
    if(c != '\0')
        printf("第一个只出现一次的字符: %c\n",c);
    else
        printf("程序出错\n");

}

int main(void)
{
    test();
    return 0;
}

题目二:字符流中第一个只出现一次的字符

请实现一个函数,用来找出字符流中第一个只出现一次的字符。例如,当字符流中只读出当前两个字符 "go” 时,第一个只出现一次的字符是 'g' ;当从该字符流中读出前 6 个字符“gegoole”时,第一个只出现一次的字符是 'l'。

解题程序:

#include<iostream>
#include<limits>
#include<stdio.h>
using namespace std;

class CharStatistics
{
public:
    CharStatistics():index(0)
    {
        for(int i=0;i<256;i++)
        {
            occurrence[i] = -1;
        }
    }
    
    void Insert(char ch)
    {
        if(occurrence[ch] == -1)
            occurrence[ch] = index;
        else if(occurrence[ch] >= 0)
            occurrence[ch] = -2;
        index++;
    }
    char FirstAppearOnce()
    {
       char ch = '\0';
        int minIndex = numeric_limits<int>::max();
        
        for(int i=0;i<256;i++)
        {
            if(occurrence[i] >=0 && occurrence[i] <minIndex)
            {
                ch = char(i);
                minIndex = occurrence[i];
            }
        }
        return ch;
    }

private:
    int index;
    int occurrence[256];

};

// 测试用例

void test()
{
    CharStatistics chars;
    chars.Insert('g');
    chars.Insert('o');
    chars.Insert('o');
    chars.Insert('g');
    chars.Insert('l');
    chars.Insert('e');

    char c = chars.FirstAppearOnce();
    if(c != '\0')
    {
       printf("字符流中只出现一次的字符是 :%c\n",c); 
    }
    else
    {
        printf("程序出错\n");
    }
}


int main(void)
{
    test();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_35396127/article/details/80214412