目录
一:两数之和
难度简单 |
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。 |
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。 |
示例: |
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1] |
解题思路
最容易想到的方法是枚举数组中的每一个数 x,寻找数组中是否存在 target - x。
当我们使用遍历整个数组的方式寻找 target - x 时,需要注意到每一个位于 x 之前的元素都已经和 x 匹配过,因此不需要再进行匹配。而每一个元素不能被使用两次,所以我们只需要在 x 后面的元素中寻找 target - x。
代码
int* twoSum(int* nums, int numsSize, int target, int* returnSize){
static int ret_nums[2] = {0};
for (i = 0; i < numsSize - 1; i++) {
for (j = i + 1; j < numsSize; j++) {
if (nums[i] + nums[j] == target) {
ret_nums[1] = j;
*returnSize = 2;
return ret_nums;
}
}
}
*returnSize = 0;
return NULL;
}
二:两数相加
难度中等 |
给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。 |
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。 |
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。 |
示例: |
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4) 输出:7 -> 0 -> 8 原因:342 + 465 = 807 |
解题思路
1:循环判断两个链表,哪个为空了就自动补0
2:取出两个链表值的和,并加上进位标志(上次求和是否进位)
3:求余保值,整除进位
代码
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) {
struct ListNode *head = NULL, *tail = NULL;
int carry = 0; //进位标志
int n1, n2, sum;
while (l1 || l2) { //循环直到两个链表都为null
n1 = l1 ? l1->val : 0; //链表为null自动补0
n2 = l2 ? l2->val : 0;
sum = n1 + n2 + carry;
if (!head) {
// 初始化head和tail,head指向结果的起始位置
head = tail = malloc(sizeof(struct ListNode));
tail->val = sum % 10; //求余保存值
tail->next = NULL;
} else {
tail->next = malloc(sizeof(struct ListNode));
tail->next->val = sum % 10;
tail = tail->next; // 表头移位便于下次赋值
tail->next = NULL;
}
carry = sum / 10; // 进位标志
if (l1) {
l1 = l1->next; // 取下一个值
}
if (l2) {
l2 = l2->next;
}
}
//最终是否需要进位
if (carry > 0) {
tail->next = malloc(sizeof(struct ListNode));
tail->next->val = carry;
tail->next->next = NULL;
}
return head;
}