【Leecode笔记之C语言】第三周(9.21-9.27)

【Day7】

第一题:宝石与石头

【Leecode笔记之C语言】第三周(9.21-9.27)_第1张图片

分析:直接在S里搜索和J相同的字符,双层for循环可实现。
问题在于:如何判断两个字符是否相等?
第一个思路:在J中存在;(strchr函数,返回在J中的位置)
第二个思路:两字符相等。(strcmp函数,比较两个字符)

int numJewelsInStones(char * J, char * S){
    int num = 0;
    //int len = S.length();
    for(int i = 0;S[i]!='\0';i++){
        if(strchr(J,S[i])){
            num++;
        }
    }
    return num;
}

【DAY8】

第二题:拿硬币

【Leecode笔记之C语言】第三周(9.21-9.27)_第2张图片

分析:数组里保存的是每堆的硬币数目,假设一堆有x个硬币,那么拿完的最少次数就是(x / 2)+(x % 2),因此遍历整个数组累加次数即可得到次数。(一次AC嘻嘻)

int minCount(int* coins, int coinsSize){
    int num = 0;
    for(int i = 0;i < coinsSize;i++){
        num += (coins[i] / 2) +(coins[i] % 2);
    }
    return num;
}

第三题:IP地址无效化

【Leecode笔记之C语言】第三周(9.21-9.27)_第3张图片

分析:C语言如何用一个字符代替另一个字符?
第一个想法:直接替代;(字符数组在最后一个字符后面加上’\0’就构成了字符串)
第二个想法:给固定位置的字符赋上其他的值;

第一次的代码:直接赋值,但是输出的结果是1,因为替换的不是同等数目的字符替换,因此替换后的字符数组的大小其实应该比原数组要大!‘.’,这是一个字符,而“[.]”是三个字符。
char * defangIPaddr(char * address){
   // int length = sizeof(address) /sizeof(address[0]);
    //for(int i = 0;i < length;i++){
        address[1] = "[.]";
        address[3] = "[.]";
        address[5] = "[.]";
   // }
    return address;
}

所以,可行的方法是,再建一个数组,然后在查找到’.‘的同时将对应位置三个数组位置赋值成’[.]’。

char * defangIPaddr(char * address){
   //int length = sizeof(address) /sizeof(address[0]);
   int length = strlen(address);//和上面那句效果一样
   //第一步,建立一个长度比原数组大7的数组;(为啥不是6)
   int defLength = length + 7;
   char * defAddress = (char *)malloc(defLength);
   //第二步,初始化数组;
   memset(defAddress,0,defLength);
   //第三步,赋值;
   //
   int step = 0;
   for(int i = 0;i < length;i++){
       if(address[i] == '.'){
           defAddress[step] = '[';
           defAddress[step+1] = '.';
           defAddress[step+2] = ']';
           step +=3;
       }
       else{
           defAddress[step] = address[i];
           step++;
       }
   }
    return defAddress;
}

稍微修改一下,结果就变成:

char * defangIPaddr(char * address){
   //int length = sizeof(address) /sizeof(address[0]);
   int length = strlen(address);//和上面那句效果一样
   //第一步,建立一个长度比原数组大7的数组;(为啥不是6)
   int defLength = length + 7;
   char * defAddress = (char *)malloc(defLength);
   //第二步,初始化数组;
   memset(defAddress,0,defLength);
   //第三步,赋值;
   //
   int step = 0;
   for(int i = 0;i < length;i++){
       if(address[i] == '.'){
           defAddress[step] = '[';
           defAddress[step++] = '.';
           defAddress[step++] = ']';
          // step +=3;
       }
       else{
           defAddress[step] = address[i];
           step++;
       }
   }
    return defAddress;
}

【Leecode笔记之C语言】第三周(9.21-9.27)_第4张图片

【DAY 9】

第四题:删除链表的节点

【Leecode笔记之C语言】第三周(9.21-9.27)_第5张图片

分析:要删除链表一个节点,第一步:找到被删除节点,第二步:将其值赋值给某空节点,第三步:让其前面的节点指向其后边的节点。

第一次代码:但是报错说head没有定义;意思就是说,存在一个我们不能直接去访问的链表head,以及给定的节点node,要在无法访问head的情况下把node节点删除。
void deleteNode(struct ListNode* node) {
    struct ListNode *L = head;
    struct ListNode *P = NULL;
    while(L->next!=NULL){
        if(L->next == node){
            p = L->next;
            L = L->next->next;
            free p;
        }
        L = L->next;
    }
}
分析:所以解决方法可以采用覆盖的方式,将要被删除节点的下一个节点覆盖被删除节点。
第二次代码:
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
void deleteNode(struct ListNode* node) {
    node->val = node->next->val;
    node->next = node->next->next;
}

第二题:整数的各位积和之差

【Leecode笔记之C语言】第三周(9.21-9.27)_第6张图片

分析:首先就是将整数的各位提取,然后进行运算即可。(一遍AC)

int subtractProductAndSum(int n){
    int sum = 0;
    int pro = 1;
    while(n!=0){
        sum += n % 10;
        pro *= n % 10;
        n /= 10;
    }
    return (pro-sum);
}

【DAY10】

第三题:按照既定顺序创建目标数组

【Leecode笔记之C语言】第三周(9.21-9.27)_第7张图片
分析:题意就是说,在新的target数组里,以index数组的值为下标,以nums的值为数组值。假如index数组没有重复数字,那么放入target就不会冲突,假如有重复数字,那么同一个位置放入不同值就会产生冲突,解决方法就是,将冲突位置及之后的数组值往后移动。(莫名想到了hash)

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* createTargetArray(int* nums, int numsSize, int* index, int indexSize, int* returnSize){
    //第一步:创建目标数组;
    int *ret = (int*)malloc(sizeof(int)*indexSize);
   // memset(target,0,length);
    for(int i = 0;i < indexSize;i++){
        if(target[i]!=null){
        //这里出错了
            for(int j = numsize-1;j >=i;j--){
                target[j+1] =target[j--]; 
            }
        }
        else{
            target[index[i]] = num[i];
        }
    }
}

重新分析:这里主要的问题就是,第一,如何找到要移动的第一个位置;第二,如何判断是否要移动。
Q:如何判断是否要移动?
A:当前面都按部就班填数时,index[i]又开始想在之前的位置填数,也就是说,当index[i] < i时。

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* createTargetArray(int* nums, int numsSize, int* index, int indexSize, int* returnSize){
    int* ret = (int*)malloc(sizeof(int) * indexSize);
    int tail = -1;
    for(int i = 0;i < indexSize;++i){
        ++tail;//表示在冲突的时候需要移动的最后一个元素;
        for(int j = tail;j > index[i];--j){
            ret[j] = ret[j-1];
        }
        //index[i]指ret数组的下标
        ret[index[i]] = nums[i];
    }
    *returnSize = indexSize;
    return ret;
}

你可能感兴趣的:(Leecode,c语言)