LeetCode学习过程-Day2

文章目录

数组

一、移除元素

27. 移除元素 - 力扣(LeetCode)

暴力法

int removeElement(int* nums, int numsSize, int val) {
    int i,j,size=numsSize;
    for(i=0;i<size;i++)
    {
        if(nums[i]==val)
        {
            for(j=i+1;j<size;j++)
                nums[j-1]=nums[j];
            i--;
            size--;
        }
    }
    return size;
}

快慢指针法

int removeElement(int* nums, int numsSize, int val) {
    int SlowIndex=0,FastIndex;
    for(FastIndex=0;FastIndex<numsSize;FastIndex++)
        if(val!=nums[FastIndex])
            nums[SlowIndex++] = nums[FastIndex];//用fastindex进行各个元素扫描,用lowindex进行元素添加
    return SlowIndex;
}

二、删除有序数组中的重复项

26. 删除有序数组中的重复项 - 力扣(LeetCode)

快慢指针法

int removeDuplicates(int* nums, int numsSize) {
    int SlowIndex = 1;
    int FastIndex = 1;
    for(;FastIndex<numsSize;FastIndex++)
            if(nums[FastIndex]!=nums[SlowIndex-1])
                nums[SlowIndex++] = nums[FastIndex];
    return SlowIndex;
}

暴力法

int removeDuplicates(int* nums, int numsSize) {
    int i=1,index=1;
    for(;i<numsSize;i++)
        {
            if(nums[i]!=nums[i-1])
                nums[index++] = nums[i];
        }
    return index;
}

三、移动零

283. 移动零 - 力扣(LeetCode)

快慢指针法

void moveZeroes(int* nums, int numsSize) {
    int SlowIndex = 0;
    int FastIndex = 0;
    for(;FastIndex<numsSize;FastIndex++)
    {
        if(nums[FastIndex])
        {
            int temp = nums[FastIndex];
            nums[FastIndex] = nums[SlowIndex];
            nums[SlowIndex] = temp;
            SlowIndex++;
        }
    }
}

四、有序数组的平方

977. 有序数组的平方 - 力扣(LeetCode)

暴力法

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* sortedSquares(int* nums, int numsSize, int* returnSize) {
    int i,j;
    (*returnSize) = numsSize;//返回数组的大小
    int* ans = malloc(sizeof(int) * numsSize);
    for(i=0;i<numsSize;i++)
        ans[i]=nums[i]*nums[i];
    for(i=0;i<numsSize;i++){
        for(j=i+1;j<numsSize;j++)
            if(ans[j]<ans[i])
            {
                int temp = ans[j];
                ans[j] = ans[i];
                ans[i] = temp;
            }
    }
    return ans;
}

//使用qsort函数,暴力法二

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
//递增
 int cmp(const void* _a, const void* _b) {
    int a = *(int*)_a, b = *(int*)_b;
    return a - b;
}
int* sortedSquares(int* nums, int numsSize, int* returnSize) {
    int i;
    (*returnSize) = numsSize;//返回数组的大小
    int* ans = malloc(sizeof(int) * numsSize);
    for(i=0;i<numsSize;i++)
        ans[i]=nums[i]*nums[i];
    /*
        qsort函数,其声明在stdlib.h文件中,时间复杂度为n*log(n)。
        功能:使用快速排序例程进行排序

        base -- 指向要排序的数组的第一个元素的指针
        nitems -- 由 base 指向的数组中元素的个数
        size -- 数组中每个元素的大小,以字节为单位
        compar -- 用来比较两个元素的函数
    */
    qsort(ans, numsSize, sizeof(int), cmp);
    return ans;
}

双指针法

第一种解法
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* sortedSquares(int* nums, int numsSize, int* returnSize) {
     (*returnSize) = numsSize;//返回数组的大小
    int* ans = malloc(sizeof(int) * numsSize);
    int i,j,pos;
    for(i=0,j=numsSize-1,pos=numsSize-1;i<=j;)
    {
        if(nums[i]*nums[i]<nums[j]*nums[j])
        {
            ans[pos] = nums[j]*nums[j];
            j--;
        }
        else{
             ans[pos] = nums[i]*nums[i];
            i++;           
        }
        pos--;
    }
    return ans;
}
第二种解法
int* sortedSquares(int* nums, int numsSize, int* returnSize) {
    int negative = -1;
    for (int i = 0; i < numsSize; ++i) {
        if (nums[i] < 0) {
            negative = i;//用于找到负数和整数的界限
        } else {
            break;
        }
    }

    int* ans = malloc(sizeof(int) * numsSize);
    *returnSize = 0;
    int i = negative, j = negative + 1;
    while (i >= 0 || j < numsSize) {
        if (i < 0) {//左边遍历完
            ans[(*returnSize)++] = nums[j] * nums[j];
            ++j;
        } else if (j == numsSize) {//右边遍历完
            ans[(*returnSize)++] = nums[i] * nums[i];
            --i;
        } else if (nums[i] * nums[i] < nums[j] * nums[j]) {
            ans[(*returnSize)++] = nums[i] * nums[i];
            --i;
        } else {
            ans[(*returnSize)++] = nums[j] * nums[j];
            ++j;
        }
    }

    return ans;
}

五、比较含退格的字符串

844. 比较含退格的字符串 - 力扣(LeetCode)

双指针法

bool backspaceCompare(char* s, char* t) {
     int i = strlen(s) - 1, j = strlen(t) - 1;
     int skipS = 0, skipT = 0;

    while (i >= 0 || j >= 0) {
        while (i >= 0) {
            if (s[i] == '#') {
                skipS++, i--;
            } else if (skipS > 0) {
                skipS--, i--;
            } else {
                break;
            }
        }
        while (j >= 0) {
            if (t[j] == '#') {
                skipT++, j--;
            } else if (skipT > 0) {
                skipT--, j--;
            } else {
                break;
            }
        }
        if (i >= 0 && j >= 0) {
            if (s[i] !=t[j]) {
                return false;
            }
        } else {
            if (i >= 0 || j >= 0) {
                return false;
            }
        }
        i--, j--;
    }
    return true;
}

重构字符串

char* build(char* str) {
    int n = strlen(str), len = 0;
    char* ret = malloc(sizeof(char) * (n + 1));
    for (int i = 0; i < n; i++) {
        if (str[i] != '#') {
            ret[len++] = str[i];
        } else if (len > 0) {
            len--;
        }
    }
    ret[len] = '\0';
    return ret;
}

bool backspaceCompare(char* S, char* T) {
    return strcmp(build(S), build(T)) == 0;
}

总结

快慢指针,快指针用于遍历元素,慢指针用于添加元素。

(*returnSize) = numsSize;//返回数组的大小。

将比较的最大的值从最后开始插入(即pos = numsSize -1),而不是从前插入。

negative = i;//用于找到负数和整数也就是0的界限,(*returnSize)=0,从最开始将小值插入,j从0往右遍历,i从接近0的负数从左遍历,重点是还要记得讨论i<0和j==numsSize的单独讨论。

用不同的skipS = 0, skipT=0来记录#的个数,如果直接为0就要用来判断是否相等,不为0就用来回退几个字符

char* ret = malloc(sizeof(char) * (n + 1));多出来的1个是\0。

遇到不是#的字符进行添加,用len来记录下标,遇到#len--来回退,最后用strcmp进行字符串比较。

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值