高频字符串问题解析

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,去重后的对数

java 版本

public static int findPairs2(int[] nums, int k) {
    // k小于0无意义
    int count = 0;
    if (nums == null || nums.length == 0 || k < 0)
        return 0;
    //这里使用了HashMap可以达到去重的目的
    Map<Integer, Integer> map = new HashMap<>();
    for (int num : nums){
        if(map.containsKey(num)){
            map.put(num,map.get(num)+1);
        }else{
            map.put(num,1);
        }
    }
    for(Integer key:map.keySet()){
        if(k==0&&map.get(key)>=2){
            count++;
        }
        if(k>0&&map.containsKey(key+k)){
            count++;
        }
    }
    return count;
}

c++版本

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,因为子串必须是连续的。

Java 版本

public class T03 {
    public static void main(String[] args) {
        String a = "hello";
        String b = "elo";
        char[] stra = a.toCharArray();
        char[] strb = b.toCharArray();
        System.out.println(judge(stra, strb));
    }

    public static boolean judge(char[] stra, char[] strb) {
        int lena = stra.length;
        int lenb = strb.length;
        int[] nums = new int[26];
        int res = 0;
        for (int i = 0; i < lenb; i++) {
            int index = strb[i] - 'a';
            nums[index]++;
            if (nums[index] == 1) res++;
        }

        for (int i = 0; i < lenb; i++) {
            int index = stra[i] - 'a';
            nums[index]--;
            if (nums[index] == 0) res--;
            if (nums[index] == -1) res++;

        }
        if (res == 0) return true;
        for (int i = lenb; i < lena; i++) {
            int index = stra[i - lenb] - 'a';
            nums[index]++;
            if (nums[index] == 0) res--;
            if (nums[index] == 1) res++;

            index = stra[i] - 'a';
            nums[index]--;
            if (nums[index] == 0) res--;
            if (nums[index] == -1) res++;
            if (res == 0) return true;
        }
        return false;
    }
}

c++ 版本

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

java版本

public class Test extends Thread {

    public static void fanzhuan(char[] str, int l, int r) {
        while (l < r) {
            char tmp = str[l];
            str[l] = str[r];
            str[r] = tmp;
            l++;
            r--;
        }
    }

    public static void fanzhuanM(char[] str) {
        fanzhuan(str, 0, str.length - 1);
        int slow = 0, fast = 0;
        while (str[fast] != ' ' && fast != str.length - 1) {
            fast++;
            if (str[fast] == ' ') {
                fanzhuan(str, slow, fast - 1);
                fast++;
                slow = fast;
            } else if (fast == str.length - 1) {
                fanzhuan(str, slow, fast);
                break;
            }
        }
    }

    public static void main(String args[]) {
        char[] str = "i am student!".toCharArray();
        System.out.println(str);
        fanzhuanM(str);
        System.out.println(str);

    }
}

方法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;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值