高频字符串问题解析

http://v.youku.com/v_show/id_XOTQ2NDc2NjY0.html?spm=a2hzp.8253869.0.0

NO1:把一个01串进行排序,你可以交换任意01位置,问最少交换次数;

NO2 找出数组中差值为k,去重后的对数

NO3  删掉一个字符串所有的a, 并且复制字符串所有的b。注意:字符数组足够大(意思就是所有操作在此数组上进行即可)

NO4 一个字符串只有*和数字构成,请把它的*都放在开头

NO5  给定两个字符串a和b,问b是否是a子串的变位词,例如输入a=hello,b=lel lle ello 都是true, 但是b=elo是false,因为子串必须是连续的。

NO6  翻转字符串, i am a student! 反转为 student! a am i



NO1:把一个01串进行排序,你可以交换任意01位置,问最少交换次数;

int Partition01(char str[], int n)

{
    int i = 0, j = n - 1, answer=0;
    while (i < j)
    {
        while (str[i] == '0'&&i < j)
            i++;
        while (str[j] == '1'&&i < j)
            j--;
        if (i < j)
        {
            i++; j--;
            ++answer;
        }            
    }
    return answer;
}
写出交换的过程!
void Partition01value(char str[], int n)
{
    int i = 0, j = n - 1;
    while (i < j)
    {
        while (str[i] == '0'&&i < j)
            i++;
        while (str[j] == '1'&&i < j)
            j--;
        if (i < j)
        {
            char tmp = str[i];
            str[i] = str[j];
            str[j] = tmp;
            i++; j--;
        }
    }
}

int main() {
    char str[] = "011001010101";
    cout << Partition01(str,strlen(str)) << endl;
    Partition01value(str, strlen(str));
    cout << str << endl;
    system("pause");
    return 0;

}

NO2 找出数组中差值为k,去重后的对数

int findPairs(vector<int> nums, int k)
{
    int count = 0, length = nums.size();
    map<int, int> numMap;//因为是去重,所以用不重复的map,而非multimap; 第一个int代表数值,第二个代表数值在数组中出现次数
    for (auto num : nums)
    {
        numMap[num]++;
    }
    for (pair<int,int> num : numMap)//pair<int,int>也可以用auto代替
    {
        if (k == 0 && num.second >= 2)
            count++;
        if (k > 0 && numMap.count(num.first + k))
            count++;
    }
    return count;
}

int main() {
    vector<int> nums{ 1,1,2, 2, 3, 4, 5, };

    cout << findPairs(nums, 0);
    system("pause");
    return 0;

}


NO3  删掉一个字符串所有的a, 并且复制字符串所有的b。注意:字符数组足够大(意思就是所有操作在此数组上进行即可)
void addDelete(char str[])
{
    int n = 0, numb = 0;
    for (int i = 0; str[i]; i++)
    {
        if (str[i] != 'a')
            str[n++] = str[i];
        if (str[i] == 'b')
            numb++;
    }
    int newn = n + numb;
    int i = n-1, j = newn-1;
    str[newn] = '\0';
    while (i >= 0 && j >= 0)
    {
        if (str[i] != 'b')
        {
            str[j--] = str[i--];
        }
        else
        {
            str[j--] = 'b';
            str[j--] = 'b';
            i--;
        }        
    }
}
int main() {
    char str[] = "aaabxswdbbbbb";
    addDelete(str);
    cout << str << endl;
    system("pause");
    return 0;

}


NO4 一个字符串只有*和数字构成,请把它的*都放在开头

方法1  数字相对顺序会发生变化(应用交换的方法来做)

void PartitionNum(char str[], int n)
{
    int i = 0, j = n - 1;
    while (i < j)
    {
        while(i<j&&str[i] == '*')
            i++;
        while (i < j&&str[j] >= '0'&&str[j] <= '9')
            j--;
        if (str[j]=='*'&&str[i]>='0'&&str[i]<='9'&&i < j)
        {
            char tmp = str[i];
            str[i] = str[j];
            str[j] = tmp;
            i++; j--;
        }
    }

}

方法2 :数字相对顺序不会发生变化(各自平移,没有交换!!)

void PartitionNum2(char str[], int n)
{
    int j = n - 1;
    //从最后开始判断如果是数字就重新从末尾开始放进数组里;
    for (int i = n - 1; i >= 0; i--)
    {
        if (isdigit(str[i]))
            str[j--] = str[i];
    }
    //剩下的就全是星号了
    for (; j >= 0; j--)
    {
        str[j] = '*';
    }

}

NO5  给定两个字符串a和b,问b是否是a子串的变位词,例如输入a=hello,b=lel lle ello 都是true, 但是b=elo是false,因为子串必须是连续的。

bool JudgeSubStr(char stra[], char strb[])
{
    int lena = strlen(stra);
    int lenb = strlen(strb);
    vector<int> num(26, 0);
    int NonZeroNum = 0;
    //获取字符串b的num和NonZeroNum信息
    for (int i = 0; i < lenb; i++)
    {
        int c = strb[i] - 'a';
        num[c]++;
        if (num[c] == 1)
            NonZeroNum++;
    }
    //测试字符串从0到lenb-1第一个滑动窗口的情况
    //注意num数组存的是stra和strb字母之差后结果存在的次数;而NonzeroNum是stra和strb字母之差num非0次的个数,如果为0就代表stra的完全滑动窗口和strb相同
    for (int i = 0; i < lenb ; i++)
    {
        int c = stra[i] - 'a';
        num[c]--;
        if (num[c] == 0)
            NonZeroNum--;
        else if (num[c] == -1)
            NonZeroNum++;
    }
    if (NonZeroNum == 0)
        return true;
    //滑动窗口开始
    for (int i = lenb; i < lena; i++)
    {
        int c = stra[i - lenb] - 'a';
        ++num[c];
        if (num[c] == 0)
            NonZeroNum--;
        else if (num[c] == 1)
            NonZeroNum++;
        c = stra[i] - 'a';
        --num[c];
        if (num[c] == -1)
            NonZeroNum++;
        else if (num[c] == 0)
            NonZeroNum--;
        if (NonZeroNum == 0)
            return true;
    }
    return false;
}


NO6  翻转字符串, i am a student! 反转为 student! a am i

方法1 我自己做法:


void swap(char &a, char&b)
{
    char tmp = a;
    a = b;
    b = tmp;
}
void ReverseWord(char *pBegin, char *pEnd)
{
    if (pBegin == NULL || pEnd == NULL)
        return;
    while (pBegin < pEnd)
    {
        swap(*pBegin, *pEnd);
        pBegin++;
        pEnd--;
    }
}

void Reverse(char *pData)
{
    if (pData == NULL)
        return;
    ReverseWord(pData, pData+strlen(pData)-1);
    char  *pBegin = pData;
    char *pEnd = pData;
    while ((*pEnd) != ' ' && (*pEnd != '\0'))
    {
        pEnd++;
        if ((*pEnd) == ' ')
        {
            ReverseWord(pBegin, pEnd - 1);
            pEnd++;
            pBegin = pEnd;
        }
        else if ((*pEnd) == '\0')
        {
            ReverseWord(pBegin, pEnd - 1);
            break;
        }
    }
}

方法2 剑指offer

char* ReverseSentence(char *pData)
{
    if(pData == NULL)
        return NULL;

    char *pBegin = pData;

    char *pEnd = pData;
    while(*pEnd != '\0')
        pEnd ++;
    pEnd--;

    // 翻转整个句子
    Reverse(pBegin, pEnd);

    // 翻转句子中的每个单词
    pBegin = pEnd = pData;
    while(*pBegin != '\0')
    {
        if(*pBegin == ' ')
        {
            pBegin ++;
            pEnd ++;
        }
        else if(*pEnd == ' ' || *pEnd == '\0')
        {
            Reverse(pBegin, --pEnd);
            pBegin = ++pEnd;
        }
        else
        {
            pEnd ++;
        }
    }

    return pData;
}

猜你喜欢

转载自blog.csdn.net/longlovefilm/article/details/79721370