21. 合并两个有序链表
将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例:
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
合并两个有序链表
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){
if(l1 == NULL) {
return l2;
} //为空结束
if(l2 == NULL) {
return l1;
} //为空结束
if(l1->val < l2->val) {
l1->next = mergeTwoLists(l1->next, l2);
return l1;
} //l1值小,返回l1;将l1->next与l2比较
else {
l2->next = mergeTwoLists(l1, l2->next);
return l2;
} //l2值小,返回l2;将l2->next与l1比较
}
88. 合并两个有序数组
给你两个有序整数数组 nums1 和 nums2,请你将 nums2 合并到 nums1 中,使 nums1 成为一个有序数组。
说明:
初始化 nums1 和 nums2 的元素数量分别为 m 和 n 。
你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。
示例:
输入:
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6], n = 3
输出: [1,2,2,3,5,6]
方法:从后向前数组遍历
因为nums1的空间都集中在后面,所以从后向前处理排序的数据会更好,节省空间,一边遍历一边将值填充进去。
时间复杂度:O(m+n)O(m+n)O(m+n)
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n){
int len1 = m-1;
int len2 = n-1;
int len = n+m-1; //指向尾部
while((len1 >= 0) && (len2 >= 0)) {
if (nums1[len1] > nums2[len2]){
nums1[len--] = nums1[len1--];
}
else {
nums1[len--] = nums2[len2--];
}
} //将较大的值填入
while(len2 >= 0) {
nums1[len--] = nums2[len2--];
} //若nums2为遍历完,将其拷贝到nums1
}
66. 加一
给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一。
最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。
你可以假设除了整数 0 之外,这个整数不会以零开头。
示例 1:
输入: [1,2,3]
输出: [1,2,4]
解释: 输入数组表示数字 123。
示例 2:
输入: [4,3,2,1]
输出: [4,3,2,2]
解释: 输入数组表示数字 4321。
加一
从后向前遍历数组
两种情况:9 非9
int* plusOne(int* digits, int digitsSize, int* returnSize){
int i;
for(i = digitsSize-1; i >= 0; i--) {
if(digits[i] == 9) {
digits[i]=0;
} //为9时,进一,置零
else {
digits[i]++;
*returnSize = digitsSize;
return digits;
} //不是9时,加一后直接返回数组
}
int *plus = (int *)malloc(sizeof(int)*(digitsSize+1)); //进一超出原数组长度时,申请新的数组
plus[0] = 1; //进一
*returnSize = digitsSize+1; //增加数组长度
for(int i = 1; i < (digitsSize+1); i++)
{
plus[i] = digits[i-1];
} //原数组赋值到新数组
return plus;
}