分析:直接在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;
}
分析:数组里保存的是每堆的硬币数目,假设一堆有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;
}
分析: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;
}
分析:要删除链表一个节点,第一步:找到被删除节点,第二步:将其值赋值给某空节点,第三步:让其前面的节点指向其后边的节点。
第一次代码:但是报错说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;
}
分析:首先就是将整数的各位提取,然后进行运算即可。(一遍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);
}
分析:题意就是说,在新的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;
}