算法小模板|双指针问题及其拓展+例题

251 阅读1分钟

本文已参加[新人创作礼]活动,一起开启掘金之路。

c+双指针-左右指针(反转字符串中的元音字母) - 反转字符串中的元音字母 - 力扣(LeetCode) (leetcode-cn.com)

//法一
	char * reverseVowels(char * s)
    {
    int i = 0,j = strlen(s)-1;
    char match[]={"AEIOUaeiou"};
    
    while(i < j)
    {
        while(i < j && strchr(match,s[i]) == NULL)
            i++;
        while(i < j && strchr(match,s[j]) == NULL)
            j--;
        
        char temp = s[i];
        s[i] = s[j];
        s[j] = temp;
        i++;
        j--;
    }
    return s;
}


//法二     字符存储   hash存储
void swap(char *a,char *b)
{
    char tem = *a;
    *a = *b;
    *b = tem;
}


char * reverseVowels(char * s)
{
    char match[10]={"aeiouAEIOU"};
    bool hash[256]={0};

    memset(hash,0,sizeof(hash));
    
    

    for(int i=0;i<10;i++)//存入原音字符
        hash[match[i]]++;
    
    int left=0,right = strlen(s)-1;

    while(left<right)
    {
        while(!hash[s[left]]&&left<right)
            left++;
        while(!hash[s[right]]&&left<right)
            right--;
        if(left<right)//如果走到这一步 证明成功匹配
            swap(&s[left++],&s[right--]);//交换之后变动i,j的值
    }
    return s;
}


//法三   基本没用
bool is_vowel(char a)
{
    switch (a) {
        case 'a':
        case 'e':
        case 'i':
        case 'o':
        case 'u':
        case 'A':
        case 'E':
        case 'I':
        case 'O':
        case 'U':
            return 1;

        default:
            return 0;
    }
}

char *reverseVowels(char *s)
{
    // 1、指针判空
    if (s == NULL)
        return NULL;

    // 2、双指针-左右指针
    int str_len = strlen(s);
    int left = 0, right = str_len - 1;
    while (left < right) 
    {
        if (!is_vowel(s[left])) 
            left++;
        if (!is_vowel(s[right])) 
            right--;
        if (is_vowel(s[left]) && is_vowel(s[right])) 
        {
            char temp = s[left];
            s[left] = s[right];
            s[right] = temp;
            left++;
            right--;
        }
    }

    return s;
}

881. 救生艇 - 力扣(LeetCode) (leetcode-cn.com)

int cmp(const void*a,const void*b)
{
    int v1 = *(int *)a;
    int v2 = *(int *)b;
    if(v1<v2)   return -1;
    else if(v1>v2) return 1;
    return 0;
}

int numRescueBoats(int* people, int peopleSize, int limit)
{
    int cnt=0;
    qsort(people,peopleSize,sizeof(people[0]),cmp);
    int left=0;
    int right=peopleSize-1;
    while(left<right)//重的人
    {
        while(left<right&&people[left]+people[right]<=limit)
        {
            left++,right--;
            cnt++;
        }
        while(left<right&&people[left]+people[right]>limit)
        {
            right--;cnt++;
        }     
       
        if(left==right)
            cnt++;
    }
    return cnt;
}

总结:

  1. 初始化两个指针位置
  2. 用while循环进行左右指针的移动 while->两个while进行指针移动 + 一个if进行判定交换