LeetCode题目归纳

1.三数之和(和为0且互不相等的三元组)

/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */
 int cmp(const void *p1, const void *p2)
 {
     return *((int *)p1)>*((int *)p2) ?1:-1;
 }
int** threeSum(int* nums, int numsSize, int* returnSize, int** returnColumnSizes){
    *returnSize=0;
    int **ans=(int **)malloc(sizeof(int *)*numsSize*numsSize);
    int i, l, r=numsSize-1, sum;
    *returnColumnSizes=(int *)malloc(sizeof(int)*numsSize*numsSize);

    if(numsSize<3) return NULL;//z在快速排序前先判断数组长度>2
    qsort(nums, numsSize, sizeof(int), cmp);

    for(i=0; i<numsSize-2; i++)
    {
        if(i>0 && nums[i]==nums[i-1])//i的大小要先写,然后再比较含i的数组元素
            continue;
        l=i+1; r=numsSize-1;
        while(l<r)
        {
            sum=nums[i]+nums[l]+nums[r];
            if(sum==0)
            {
                ans[*returnSize]=(int *)malloc(sizeof(int)*3);
                (*returnColumnSizes)[*returnSize]=3;
                ans[*returnSize][0]=nums[i];
                ans[*returnSize][1]=nums[l];
                ans[*returnSize][2]=nums[r];
                *returnSize+=1;   //曾错 *returnSize++是指针移动,而非数值增加!而+=的优先级就小很多,不会出现这样的问题
                l++; r--;
                while(l<r && nums[l]==nums[l-1]) l++;
                while(l<r && nums[r]==nums[r+1]) r--;
            }
            else if(sum<0) l++;
            else if(sum>0) r--;
        }
    }
    return ans;
}

2.荷兰国旗问题

void sortColors(int* nums, int numsSize){
    int l=0, r=numsSize-1, p=0;//保证l的左侧是小数,r的右侧是大数,p的范围是[l, r]。
    int val=1, temp;
    while(p<=r)
    {
        if(nums[p]>val)//要移动(交换)到右区间
        {
            temp=nums[p]; nums[p]=nums[r]; nums[r]=temp;
            r--;   //p位置不动,继续判断交换来的数的大小
        }
        else if(nums[p]<val)//交换到左区间
        {
            temp=nums[p]; nums[p]=nums[l]; nums[l]=temp;
            l++; p++;   //由于p指针是从左往右移动,所以p经过的区域(p及其左侧)元素(尤其是nums[l])小于等于nums[p],并且在[l, p-1]区间范围必有nums[i]==nums[p].
        }
        else//若相等,则指针继续移动
            p++;
    }
}

3.合并区间(56.)//LeetCode的代码格式实例(对各形参的操作)

​

/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */
int cmp(const void *p1, const void *p2)
{
    //这里的排序法与普通的二维数组又有所不同,因为比较的是malloc申请的二维数组(动态)
    return (*(int **)p1)[0]>(*(int **)p2)[0]?1:-1;//曾错 这里是比较数组的第一个元素;且要用()
}

int** merge(int** intervals, int intervalsSize, int* intervalsColSize, int* returnSize, int** returnColumnSizes){
    int **ans=(int **)malloc(sizeof(int *)*intervalsSize);
    *returnSize=0;//是2*组数
    *returnColumnSizes=(int *)malloc(sizeof(int)*intervalsSize*2);//有m个2的数组
    //intervalsColSize是干什么用的?
    qsort(intervals, intervalsSize, sizeof(intervals[0]), cmp);
    //printf("[%d,%d]\n", intervals[0][0], intervals[0][1]);

    ans[0]=(int *)malloc(sizeof(int)*2);
    ans[0][0]=intervals[0][0]; ans[0][1]=intervals[0][1];
    (*returnColumnSizes)[0]=2; *returnSize+=1;   //曾错 函数调用的变量,考虑是否加*和()
    for(int i=1, j=0; i<intervalsSize; i++)//j为待增区间,i为检查区间
    {
        if(intervals[i][0]<=ans[j][1])
        {
            ans[j][1] = (intervals[i][1]>ans[j][1]? intervals[i][1]: ans[j][1]);
        }
        else if(intervals[i][0]>ans[j][1])
        {
            ans[++j]=(int *)malloc(sizeof(int)*2);
            ans[j][0]=intervals[i][0]; ans[j][1]=intervals[i][1];
            (*returnColumnSizes)[j]=2;
            *returnSize+=1;//对长度的统计可以在循环内实时跟进(推荐),也可以结束后再循环一次来判断
        }
    }
    return ans;
}

[点击并拖拽以移动]
​

4.螺旋矩阵2(59.)//此思路易错,思路看题解

/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */
int** generateMatrix(int n, int* returnSize, int** returnColumnSizes){
    *returnSize=n;
    *returnColumnSizes=(int *)malloc(sizeof(int)*n);
    for(int i=0; i<n; i++)
        (*returnColumnSizes)[i]=n;//到底要怎么写
    int temp=1, round=0, row, col;
    int **ret=(int **)malloc(sizeof(int *)*n);
    for(int i=0; i<n; i++)
    {
        ret[i]=(int *)malloc(sizeof(int)*n);
        memset(ret[i], 0, sizeof(int)*n);
    }
        

    while(round<(n+1)/2)// && temp<=*returnSize)//唉,每个while循环的结尾都要看判断条件的变量是否处理完毕,然后继续判断(比如这里不能用<=;?)
    {
        for(row=round, col=round; col<n-1-round; col++, temp++)//经典循环条件【记】
            ret[row][col]=temp;
        for(; row<n-1-round; row++, temp++)
            ret[row][col]=temp;
        for(; col>round; col--, temp++)
            ret[row][col]=temp;
        for(; row>round; row--, temp++)
            ret[row][col]=temp;
        //printf("%d ", temp);
        round++;//差点忘了
    }
    if(n%2!=0)   //上述循环操作的尾部缺陷
        ret[n/2][n/2]=temp;
    return ret;
}

5.搜索二维矩阵2(240.)

(1)错误版本

        错误原因:“/”上的数字不一定是下一“斜”的都比上一“斜”的大

#define myMin(a, b) ((a)>(b)?(b):(a))
bool searchMatrix(int** matrix, int matrixSize, int* matrixColSize, int target){
    int m=matrixSize, n=matrixColSize[0];//m为行,n为列
    int row=0, col=0, p1=0, p2=m+n-2, mid=(p1+p2)/2;
    int max=-100000000, min=100000000;
    while(p1<=p2)
    {
        mid=(p1+p2)/2;
        max=-100000000, min=100000000;   //曾错 最大值max和最小值min在这里因为改变数据范围,所以也要每次更新
        //死循环原因:1.某些数据没更新;2.循环的判断条件某变量在操作中被改变而不是常值;3.if和else if的判断都不符合,从而没有移动指针
        
            printf("[%d %d %d] ", p1, mid, p2);
            for(row=myMin(mid, m-1), col=mid-row; col<n && row>=0; row--, col++)   //条件 为坐标在范围内 即可
            {
                if(matrix[row][col]>max) max=matrix[row][col];
                if(matrix[row][col]<min) min=matrix[row][col];
                if(matrix[row][col]==target) return true;
            }
            printf("{%d %d} ", min, max);
            if(target>max) 
                p1=mid+1;
            else if(target<min)
                p2=mid-1;
            else 
                return false;   //曾错 如果找不到,少了这句的话,就会陷入死循环
    }
    return false;
}

(2)修改版本

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值