法一:记忆化递归
int climbStairsRecursive(int n, int* memo) {if (n <= 2) {return n;}if (memo[n] > 0) {return memo[n];}memo[n] = climbStairsRecursive(n - 1, memo) + climbStairsRecursive(n - 2, memo);return memo[n];
}int climbStairs(int n) {int* memo = (int*)malloc((n + 1) * sizeof(int));if (memo == NULL) {return -1; // 内存分配失败}memset(memo, 0, (n + 1) * sizeof(int));int result = climbStairsRecursive(n, memo);free(memo);return result;
}
法二:动态规划
int climbStairs(int n) {int p = 0, q = 0, r = 1;for (int i = 1; i <= n; ++i) {p = q;q = r;r = p + q;}return r;
}
尽管代码中没有明确地使用一个数组来存储状态,但是动态规划的核心思想仍然被运用了:将问题分解成子问题,利用已经求解过的子问题的解来求解当前问题。
int* intersection(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize) {int hash[1000] = {0}; // 将 hash 数组初始化为 0int* res = (int*)malloc(sizeof(int) * nums1Size); // 根据 nums1 的大小来动态分配内存*returnSize = 0; // 初始化返回数组的大小为 0// 遍历 nums1,将 nums1 中的元素作为 hash 数组的下标,标记出现过的数字for(int i = 0; i < nums1Size; i++) {hash[nums1[i]] = 1;}// 遍历 nums2,如果 nums2 中的元素在 hash 中出现过,则将其添加到返回数组中for(int j = 0; j < nums2Size; j++) {if(hash[nums2[j]] == 1) {res[(*returnSize)++] = nums2[j];hash[nums2[j]] = 0; // 避免重复添加相同的数字,这里很巧妙,添加了一次将hash对应改为0//下一次就算是相同的数字也匹配不了了}}return res;
}
struct hashTable{int key;int val;UT_hash_handle hh;
};int fourSumCount(int* nums1, int nums1Size, int* nums2, int nums2Size, int* nums3, int nums3Size, int* nums4, int nums4Size){struct hashTable*hashtable=NULL;for(int i=0;i<nums1Size;i++){for(int j=0;j<nums2Size;j++){int ikey=nums1[i]+nums2[j];struct hashTable*tmp;HASH_FIND_INT(hashtable,&ikey,tmp);if(!tmp){struct hashTable*tmp=malloc(sizeof(struct hashTable));tmp->key=ikey;tmp->val=1;HASH_ADD_INT(hashtable,key,tmp);}else{tmp->val++;}}}int ans=0;for(int i=0;i<nums3Size;i++){for(int j=0;j<nums4Size;j++){int ikey=-(nums3[i]+nums4[j]);struct hashTable*tmp;HASH_FIND_INT(hashtable,&ikey,tmp);if(tmp){ans+=tmp->val;}}}return ans;
}
先遍历A,B再遍历C,D算法时间复杂度为n的平方,先遍历A,再遍历B,C,D算法时间复杂度是n的三次方,所以我们采用两个for循环比较好
key表示节点的值,val表示这个值在两个数组A,B组合出现过几次
第一个两重for循环先遍历所有A,B数组的所有值,然后记录次数
第二个两重for循环也同样遍历所有C,D所能构成的值,如果其相反数在哈希表中可以找的到的话,就ans加上第一个双层for记录的出现的次数
参考:【学透哈希表,map使用有技巧!LeetCode:454.四数相加II-哔哩哔哩】 https://b23.tv/diFkLwW
void HASH_ADD_INT(hh, head, add);
其中:
hh
是哈希表中用于链接的哈希结构体的字段名。head
是指向哈希表的指针的名称。add
是要添加到哈希表中的结构体节点的指针。
在您的代码中,HASH_ADD_INT(hashtable, key, tmp);
的作用是将指向结构体节点 tmp
的指针添加到名为 hashtable
的哈希表中。key
是结构体中用于作为键值的整数字段的名称。