双指针

  1. 验证回文字符串 Ⅱ
    当左指针和右指针所指向的值不想等时,删除一个字符有两种情况,从左删或者从右删。此时,左指针的左边和右指针的右边已经是对称的了,只用判断s[i+1]-s[j] 或者 s[i]-s[j-1]的对称性
bool validPalindrome(char * s){
    for (int i = 0, j = strlen(s)-1; i < j; ++i, --j) 
        if (s[i] != s[j]) 
            return (judge(s, i+1,j) || judge(s, i,j-1)); 
    return true;
}
int judge(char *str, int i, int j) {
    while (i < j) if (str[i++] != str[j--]) return false;
    return true;
}
  1. 反转字符串中的元音字母
    拿到这题,我在想,what?元音字母是什么来着,hhhhhhh
    在i<j的情况,i负责从左到右找元音字母,j负责从右到左找元音字母,然后交换即可
int vowel(char c)
{
    if(c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u' ||
        c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U')
        return 1;
    else
        return 0;
}
char * reverseVowels(char * s){
    int i = 0, j = strlen(s) - 1;
    char t;
    while(i < j){
        while(i < j && !vowel(s[i]))
            i++;
        while(i < j && !vowel(s[j]))
            j--;
        t = s[i];
        s[i] = s[j];
        s[j] = t;
        i++;
        j--;
    }
    return s;
}
  1. 平方数之和
    需要注意的就是j的取值即可
bool judgeSquareSum(int c){
    long i=0,j=sqrt(c),num;
    while(i<=j){
        num=i*i+j*j;
        if(num==c)
            return true;
        else if(num>c){
            j--;
        }else 
            i++;
    }
    return false;
}
  1. 两数之和 II - 输入有序数组
    注意已知条件,数组已升序排列了,又是找两数,很容易想到双指针哈
int* twoSum(int* numbers, int numbersSize, int target, int* returnSize){//注意升序
    int* result=(int *)malloc(sizeof(int)*2);
    int i=0,j=numbersSize-1,sum;
    /*for(i=0;i<numbersSize-1;i++){//第一遍的写法又少情况了
        if((numbers[i]+numbers[i+1])==target)
            result[0]=i+1;
            result[1]=i+2;
    }*/
    while(i<j){
        sum=numbers[i]+numbers[j];
        if(sum==target){
            result[0]=i+1;
            result[1]=j+1;
            *returnSize=2;
            return result;
        } 
        else if(sum>target)
            j--;
        else
            i++;
    }
    return NULL;
}
  1. 合并两个有序数组
    注释掉的部分,正序插入的,是我第一遍想到的,需要想的情况较多喃,看到不舒服。
    第二种是倒序的情况,清晰明了些,因为两个数组本来就是有序的嘛
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n){
    /*int i,j,k,x;
    for(i=0;i<n;i++){//i遍历的是nums2
        for(j=0;j<nums1Size;j++){//j遍历的是nums1,被插入的数组
            if(nums1[j]>nums2[i])
                break;
        }
        if(j<nums1Size){//就是这种情况没有讨论完,万一nums2中剩下的数都比num1中大的情况
            for(k=nums1Size-1;k>j;k--){
                nums1[k]=nums1[k-1];
            }
            nums1[j]=nums2[i];
        }else{
            x=nums1Size-1;
            for(k=n-1;k>=i;k--){
                nums1[x--]=nums2[k];
            }
            return;
        }
    }*/
    int index1 = m - 1, index2 = n - 1;
    int indexMerge = m + n - 1;
    while (index1 >= 0 || index2 >= 0) {
        if (index1 < 0) {
            nums1[indexMerge--] = nums2[index2--];
        } else if (index2 < 0) {
            nums1[indexMerge--] = nums1[index1--];
        } else if (nums1[index1] > nums2[index2]) {
            nums1[indexMerge--] = nums1[index1--];
        } else {
            nums1[indexMerge--] = nums2[index2--];
        }
    }
}
  1. 环形链表
    这道题非常典型,不用多说什么
bool hasCycle(struct ListNode *head) {//典型的快慢指针
    if(head==NULL)
        return false;
    struct ListNode *slow=head,*fast=head->next;
    while(fast!=NULL&&slow!=NULL&&fast->next!=NULL)//至少存在两个点及以上才能成环
    {
        if(fast->val==slow->val)
            return true;
        slow=slow->next;
        fast=fast->next->next;
    }
    return false;
}
  1. 通过删除字母匹配到字典里最长单词
    其实就是考查字符串数组中,是否有s的子序列,如果有,则继续判断是不是最长,字典排序最小的。否则返回空。
    顺带再注意一下二级指针的使用,有点遗忘了
bool IsSubtr(char *s1,char *s2){//s1为s
    int length1=strlen(s1),length2=strlen(s2),i=0,j=0;
    while(i<length1&&j<length2){
        if(s1[i]==s2[j])
            j++;
        i++;
    }
    return j==length2;
}
char * findLongestWord(char * s, char ** d, int dSize){//对,子序列问题,一个串用一个变量遍历即可,而不是我想的两个变量遍历一个字符串哟
    int i,maxLength=0;
    char *p,*longWord="";
    for(i=0;i<dSize;i++){
        maxLength=strlen(longWord);
        p=d[i];
        if((strlen(p)==maxLength&&strcmp(p,longWord)>0)||strlen(p)<maxLength)
            continue;
        if(IsSubtr(s,p)){
            longWord=p; 
        }     
    }
        return longWord;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值