数组

804. 唯一摩尔斯密码词

这次没有任何技巧而言,感觉就是再次熟悉一下,二级指针空间的分配回收,库函数strcat()的使用

int uniqueMorseRepresentations(char ** words, int wordsSize){
    char mossCode[26][5] = {
        ".-","-...","-.-.","-..",".","..-.","--.","....","..",".---",
        "-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-",
        "..-","...-",".--","-..-","-.--","--.."
    };
    char **result=(char **)malloc(sizeof(char *)*wordsSize);
    for (int i = 0; i < wordsSize; i++) {
         result[i]=(char *)malloc(sizeof(char)*49);//字符串最长为4,4*12+1
        memset(result[i], 0, sizeof(char)*49);
    }

    int i,length,j,sum=0;
    for(i=0;i<wordsSize;i++){
        length=strlen(*(words+i));//行指针
        for(j=0;j<length;j++){
            strcat(result[i],mossCode[words[i][j]-'a']);//计算出words[i]的mosscode
        }
    }
    for(i=0;i<wordsSize;i++){
        for(j=i+1;j<wordsSize;j++){
            if(strcmp(result[i],result[j])==0)
                break;
        }
        if(j==wordsSize)
            sum++;
    }
    for(i=0;i<wordsSize;i++)
        free(result[i]);
    free(result);
    return sum;
}

1351. 统计有序矩阵中的负数

注意利用好,每行每列都是非递增排序就OK拉

int countNegatives(int** grid, int gridSize, int* gridColSize){
    int i,j,m=gridSize,n=*gridColSize,sum=0,tap;
    for(i=0;i<m;i++){
        for(j=n-1;j>=0;j--){
                if(grid[i][j]>=0){
                    tap=0;
                    break;
                }
                tap=-1;
        }
        if(tap==-1){
            sum+=n;
        }else{
            sum+=n-j-1;
        }
    }
    return sum;
}

1337. 方阵中战斗力最弱的 K 行

总的来说来说,是一个排序题,外加索引绑定(索引绑定可以用二维数组,也可结构体,至于其他方法,还没去了解)。
定义结构体大小不能用变量,阿偶
结构体学的很潜,我都不知道qsort能和结构体组合使用。returnSize是返回给主函数,来控住数组的打印的。

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
struct Node{
     int index;
     int power;
 };
 int cmp(const void *a,const void *b){
     return (*(struct Node *)a).power - (*(struct Node *)b).power;//a-b从小到大排序b-a则为从大到小排序
 }
int* kWeakestRows(int** mat, int matSize, int* matColSize, int k, int* returnSize){
    int i,j,m=matSize,n=*matColSize;
    struct Node nodes[101]={0};
    for(i=0;i<m;i++){
        nodes[i].index=i;
        for(j=0;j<n;j++){
            if(mat[i][j]==1){   
                nodes[i].power++;
            }    
        }
    }
    qsort(nodes,m,sizeof(struct Node),cmp);
    int *res = (int *)malloc(k * sizeof(int));
    memset(res, 0, k * sizeof(int));
    (*returnSize) = k;//估计主函数中调用了此形参
    for(i=0;i<k;i++){
        res[i]=nodes[i].index;
    }
    return res;
}

717. 1比特与2比特字符

这道题的思路还是满简单的。遍历到的数若为1,则i增2(因为只要遇到1。10,11都是存在的情况),反之则增1。对于0可以是单独的0,或者10,也即只有在最后两位为00的情况下,给定的字符串才是以0结束的。所以我们对0以及他的前一位进行校验即可。情况一共有两种(以下情况,i均指向数组bitsSize的倒数第二个数):

  1. 最后两位为00,因为bits[bitsSize-1]==0,所以循环结束的时候,字符串刚好以0结束
  2. 最后两位为10,最后循环结束i==bitsSize,越界拉
bool isOneBitCharacter(int* bits, int bitsSize){
    int i;
    bool flag=false;
    for(i=0;i<bitsSize-1;){//前四次按照普通的循环写的结束条件为bitsSize,然后一直错一直错,搞的我怀疑人生,以为for中三个表达式的执行顺序记错了
        if(bits[i]==1)
            i+=2;
        else
            ++i;
    }
    if(i==bitsSize-1)
        flag=true;
    return flag;
}

136. 只出现一次的数字

这道题的方法涉及到我的知识盲区,位运算的实际运用。但是在理论上我又是懂位运算的。下面我先讲讲我遇到这题时候的一些想法。
1.用额外的空间,且额外空间还未知,因为我不知道最大的数是几
在这里插入图片描述
[]中的数为给定的一组数,蓝色的数组为新开辟的数组。eg:第一位数字为4,则new[4]++;

  1. 先将nums排序,但我想到最快的方法就是快排,也要nlogn。
  2. 第三个当然就是大神的方法咯,位运算!!!
    C语言位运算符:与(&)、或(|)、异或(^)、取反(!)、左移(<<)与右移(>>)。这些运算符只能用于整型操作数,即只能用于带符号或无符号的char,short,int与long类型。
    异或运算具有交换律,也即进行运算时的顺序不会改变结果。[4,1,2,1,2],4——100(2),1——001(2),2——010(2),100001010001010=100
int singleNumber(int* nums, int numsSize){
    int temp=nums[0],i;
    if(numsSize>1){
        for(i=1;i<numsSize;i++){
            temp^=nums[i];
        }
    }
    return temp;
}

1207. 独一无二的出现次数

  1. 因为arr[i]的范围是给定了的,所以可以用此方法。
  2. count1[]中最多只有arrSize个不为0的数,所以只用给count2[]申请arrSize个空间
  3. count1[]用于记录各个数出现的次数;count2[]用于记录次数的个数
  4. 既然我浪费了空间,不想在排序浪费时间了,所以用了count2[]
    既然我浪费了空间,不想在排序浪费时间了
bool uniqueOccurrences(int* arr, int arrSize){
    int i,j;
    bool temp=true;
    int *count1=(int *)malloc(sizeof(int)*2001);
    memset(count1,0,sizeof(int)*2001);
    int *count2=(int *)malloc(sizeof(int)*(arrSize+1));
    memset(count2,0,sizeof(int)*(arrSize+1));
    for(i=0;i<arrSize;i++){
        if(arr[i]>=0)
            count1[arr[i]]++;
        else
            count1[arr[i]+2000]++;
    }
    for(j=0;j<2001;j++){
        if(count1[j]>0)
            count2[count1[j]]++;
        if(count2[count1[j]]>1)
            temp=false;
    }
    free(count1);
    free(count2);
    return temp;
}

54. 螺旋矩阵

注意墙壁的更新,这道题我自己在DEVc++ 5.11里调试过,然后喃,将二维数组直接传给二级指针是会报错的,原因是因为二维数组的二维是个假概念,在实际存储中都是一维存储,所以会报错。那么改为传指针数组就好拉……

int* spiralOrder(int** matrix, int matrixSize, int* matrixColSize, int* returnSize){
    if(matrixSize==0){//注意考虑为空的情况
        *returnSize=0;
        return 0;
    }     
    int left=0,right=*matrixColSize-1,up=0,down=matrixSize-1,length=matrixSize*(*matrixColSize);
    int i,j,k=0;//i,j交替动
    int *res=(int *)malloc(sizeof(int)*length); 
    while(left<=right&&up<=down&&k<length){//往右 
        i=up,j=left;
        while(j<=right&&k<length){
            res[k]=matrix[i][j];
            k++;
            j++;
        }  
        up++;
        i=up;
        j=right;
        while(i<=down&&k<length){//往下 
            res[k]=matrix[i][j];
            k++;
            i++;
        }
        right--;
        i=down;
        j=right;
        while(j>=left&&k<length){//往左 
            res[k]=matrix[i][j];
            k++;
            j--;
        }
        down--;
        i=down;
        j=left;
        while(i>=up&&k<length){//往上 
            res[k]=matrix[i][j];
            k++;
            i--;
        }
        left++;
        i=up;
        j=left;
    }
    *returnSize=length;
    return res;
} 

1. 两数之和

用了一个qsort,c自带的快排函数

struct Node{
     int index;
     int power;
 };
int cmp(const void *a,const void *b){
     return (*(struct Node *)a).power - (*(struct Node *)b).power;//a-b从小到大排序b-a则为从大到小排序
 }
int* twoSum(int* nums, int numsSize, int target, int* returnSize){//双指针走起,哎,需要排序
     int i,l=0,r=numsSize-1;
    int mid=0;
    int *res=(int *)malloc(sizeof(int)*2);
    struct Node *nodes=(struct Node *)malloc(sizeof(struct Node)*numsSize);
    for(i=0;i<numsSize;i++){
        nodes[i].index=i;
        nodes[i].power=nums[i];
    }
    qsort(nodes,numsSize,sizeof(struct Node),cmp);//索引绑定已就绪,排序没起作用
    while(l<r){
        if((nodes[l].power+nodes[r].power)==target){
            res[0]=nodes[l].index;
            res[1]=nodes[r].index;
            *returnSize=2;
            return res;
        }else if((nodes[l].power+nodes[r].power)<target)
            l++;
        else
            r--; 
    }
    *returnSize=2;
    return 0;
}

66. 加一

一遍AC,现在自己解题的时候,也记得要考虑多种情况了。

int* plusOne(int* digits, int digitsSize, int* returnSize){
    int *res=(int *)malloc(sizeof(int)*(digitsSize+1));
    int j=digitsSize-1,carry=1;
    for(j=digitsSize-1;j>=0;j--){
        digits[j]=digits[j]+carry;
        if(digits[j]>=10){
            carry=1;
            digits[j]=digits[j]-10;
        }
        else
            carry=0;
        res[j+1]=digits[j];    
    }
    if(carry==1){//最高位的进位
        res[0]=1;
        *returnSize=digitsSize+1;
    }
    else{
        res=res+1;
        *returnSize=digitsSize;
    }
    return res;
}

1356. 根据数字二进制下 1 的数目排序

排序用了很Low的冒泡

int* sortByBits(int* arr, int arrSize, int* returnSize){//count记录每个数字包含1的个数
    int i,j,temp;
    int *count=(int *)malloc(arrSize*sizeof(int));
    memset(count,0,arrSize*sizeof(int));
    int *arr1=(int *)malloc(arrSize*sizeof(int));
    memset(arr1,0,arrSize*sizeof(int));
    memcpy(arr1,arr,sizeof(int)*arrSize);
    for(i=0;i<arrSize;i++){
        while(arr1[i]>0){
            temp=arr1[i]%2;
            if(temp==1)
                count[i]++;
            arr1[i]=arr1[i]/2;
        }      
    }

    for (i=0;i<arrSize-1;i++){
        bool flag=false;
        for (j=0;j<arrSize-1-i;j++){
            if (count[j] >count[j+1] || (arr[j]>arr[j+1]&&count[j]==count[j+1])){
                
                temp = count[j];
                count[j] = count[j+1];
                count[j+1] = temp;
                
                temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;

                flag=true;
            }
        }
        if(flag==false)
            break;
    }
    
    (*returnSize)=arrSize;
    free(count);
    free(arr1);
    return arr;
}
}

349. 两个数组的交集

放两个版本,当然是先放最新的咯,看看自己最开始写的,觉得蠢得不行。
所以遇到数组题,先想想排序吧

int cmp(const void *a,const void *b){
     return (*(int *)a) - (*(int *)b);//a-b从小到大排序b-a则为从大到小排序
 }
int* intersection(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize){
    //写数组题,一般都要先进行排序处理
     if (!nums1 || !nums2) {
        *returnSize = 0;
        return NULL;
    }
    int *res=(int *)malloc(sizeof(int)*(nums1Size<nums2Size? nums1Size:nums2Size));
    int i,j,count=0;//分别用于遍历数组nums1和数组nums2
    qsort(nums1,nums1Size,sizeof(int),cmp);
    qsort(nums2,nums2Size,sizeof(int),cmp);
    for(i=0,j=0;i<nums1Size&&j<nums2Size;){
        if(nums1[i]<nums2[j]){
            i++;
        }else if(nums1[i]>nums2[j]){
            j++;
        }else{
            res[count++]=nums1[i];
            i++;
            j++;
            if(count>1&&res[count-1]==res[count-2])
                count--;
        }
    }
    *returnSize=count;
    res = (int *)realloc(res, count* sizeof(int));//扩内存的时候慎用,这是缩内存,所以还行
    return res;
}
int* intersection(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize){
    int i,j,k=0,temp;
    if(nums2Size>nums1Size)
        temp=nums2Size;
    else
        temp=nums1Size;
    int *result=(int *)malloc(sizeof(int)*temp);
    memset(result,0,sizeof(int)*temp);
    for(i=0;i<nums1Size;i++){
        for(j=0;j<nums2Size;j++){
            if(nums1[i]==nums2[j]){//没有判断result里的数是否重复
                result[k]=nums1[i];     
                k++;
                break;
            }     
        }
    }
    for (i=0;i<k;i++){ 
        for (j=0;j<k-1-i;j++){
            if (result[j] > result[j+1]){
                temp = result[j];
                result[j] = result[j+1];
                result[j+1] = temp;
            }
        }
    }
    if(k==0){
        (*returnSize)=0;
        return result;
    }else{
        for(i=0,j=1;j<k;j++)//我的天,用的这个删除重复数字的方法,要求是有序的。半天了才发现,呜呜呜
            if(result[i]!=result[j])
                result[++i]=result[j];
     (*returnSize)=i+1;
     return result;
    }
}

26. 删除排序数组中的重复项

这题的思维和上一题的第二版中我用的那个排序方法是一样的

int removeDuplicates(int* nums, int numsSize){//双指针,前提是有序,这题已经有序了
    int i=0,j;//i为新数组的下标
    if(numsSize==0)
        return 0;
    for(j=0;j<numsSize;j++){
        if(nums[j]!=nums[i])
            nums[++i]=nums[j];
    }
    return i+1;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值