合并两个有序数组:
给你两个按 非递减顺序 排列的整数数组
nums1
和nums2
,另有两个整数m
和n
,分别表示nums1
和nums2
中的元素数目。请你 合并
nums2
到nums1
中,使合并后的数组同样按 非递减顺序 排列。注意:最终,合并后数组不应由函数返回,而是存储在数组
nums1
中。为了应对这种情况,nums1
的初始长度为m + n
,其中前m
个元素表示应合并的元素,后n
个元素为0
,应忽略。nums2
的长度为n
。示例 1:
输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3 输出:[1,2,2,3,5,6] 解释:需要合并 [1,2,3] 和 [2,5,6] 。 合并结果是 [1,2,2,3,5,6] ,其中斜体加粗标注的为 nums1 中的元素。示例 2:
输入:nums1 = [1], m = 1, nums2 = [], n = 0 输出:[1] 解释:需要合并 [1] 和 [] 。 合并结果是 [1] 。示例 3:
输入:nums1 = [0], m = 0, nums2 = [1], n = 1 输出:[1] 解释:需要合并的数组是 [] 和 [1] 。 合并结果是 [1] 。 注意,因为 m = 0 ,所以 nums1 中没有元素。nums1 中仅存的 0 仅仅是为了确保合并结果可以顺利存放到 nums1 中。
两种方法都是从后向前来 进行比较,然后赋值给后面的元素慢慢向前。
指针:
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) {
int i = m - 1; // nums1有效元素末尾
int j = n - 1; // nums2末尾
int k = m + n - 1; // 合并后数组末尾
// 从后向前比较并填充
while (i >= 0 && j >= 0) {
if (nums1[i] > nums2[j]) {
nums1[k--] = nums1[i--];
} else {
nums1[k--] = nums2[j--];
}
}
// 处理nums2剩余元素
while (j >= 0) {
nums1[k--] = nums2[j--];
}
}
这里为什么没有
// 处理nums1剩余元素
while (i >= 0) {
nums1[k--] = nums2[i--];
}这里的代码呢? 因为nums1本身就是有序的所以不需要这个
完整代码:
#include <stdio.h>
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) {
int p1 = m - 1, p2 = n - 1, tail = m + n - 1;
while (p2 >= 0) { // 只需处理nums2剩余元素
if (p1 >= 0 && nums1[p1] > nums2[p2]) {
nums1[tail--] = nums1[p1--];
} else {
nums1[tail--] = nums2[p2--];
}
}
}
int main() {
int m, n;
scanf("%d %d", &m, &n);
int nums1[200] = {0}, nums2[200] = {0};
// 输入nums1有效元素
for (int i = 0; i < m; i++) {
scanf("%d", &nums1[i]);
}
// 输入nums2
for (int i = 0; i < n; i++) {
scanf("%d", &nums2[i]);
}
merge(nums1, m+n, m, nums2, n, n);
// 输出结果
for (int i = 0; i < m+n; i++) {
printf("%d ", nums1[i]);
}
return 0;
}
冒泡排序:
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) {
// 1. 将 nums2 追加到 nums1 尾部
for (int i = 0; i < n; i++) {
nums1[m + i] = nums2[i];
}
// 2. 整体排序(这里用冒泡排序示意,实际应调用库函数)
for (int i = 0; i < m + n; i++) {
for (int j = 0; j < m + n - i - 1; j++) {
if (nums1[j] > nums1[j + 1]) {
int temp = nums1[j];
nums1[j] = nums1[j + 1];
nums1[j + 1] = temp;
}
}
}
}
移除元素:
给你一个数组
nums
和一个值val
,你需要 原地 移除所有数值等于val
的元素。元素的顺序可能发生改变。然后返回nums
中与val
不同的元素的数量。假设
nums
中不等于val
的元素数量为k
,要通过此题,您需要执行以下操作:
- 更改
nums
数组,使nums
的前k
个元素包含不等于val
的元素。nums
的其余元素和nums
的大小并不重要。- 返回
k
。
快慢指针:
int removeElement(int* nums, int numsSize, int val) {
int slow = 0;
for (int fast = 0; fast < numsSize; fast++) {
if (nums[fast] != val) {
nums[slow++] = nums[fast];
}
}
return slow;
}
遍历:
int removeElement(int* nums, int numsSize, int val) {
int left = 0; // 初始化左指针
int right = numsSize - 1; // 初始化右指针
while (left <= right) {
if (nums[left] == val) {
// 如果左指针指向的元素等于目标值,则将右指针指向的元素移到左指针位置
nums[left] = nums[right];
right--; // 右指针向左移动
} else {
left++; // 否则左指针向右移动
}
}
return left; // 返回不等于val的元素个数
}
删除有序数组中的重复项:
给你一个 非严格递增排列 的数组
nums
,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回nums
中唯一元素的个数。考虑
nums
的唯一元素的数量为k
,你需要做以下事情确保你的题解可以被通过:
- 更改数组
nums
,使nums
的前k
个元素包含唯一元素,并按照它们最初在nums
中出现的顺序排列。nums
的其余元素与nums
的大小不重要。- 返回
k
。
int removeDuplicates(int* nums, int numsSize) {
if (numsSize == 0) return 0;
int slow = 0;
for (int fast = 1; fast < numsSize; fast++) {
if (nums[fast] != nums[slow]) {
slow++;
nums[slow] = nums[fast];
}
}
return slow + 1;
}
删除有序数组中的重复项2:
给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使得出现次数超过两次的元素只出现两次 ,返回删除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
int removeDuplicates(int* nums, int numsSize) {
if (numsSize <= 2) return numsSize;
int slow = 1;
for (int fast = 2; fast < numsSize; fast++) {
if (nums[fast] != nums[slow-1]) {
slow++;
nums[slow] = nums[fast];
}
}
return slow + 1;
}
多数元素:
给定一个大小为
n
的数组nums
,返回其中的多数元素。多数元素是指在数组中出现次数 大于⌊ n/2 ⌋
的元素。你可以假设数组是非空的,并且给定的数组总是存在多数元素。
示例 1:
输入:nums = [3,2,3] 输出:3示例 2:
输入:nums = [2,2,1,1,1,2,2] 输出:2
单层循环:
int majorityElement(int* nums, int numsSize) {
int count;
int times = numsSize / 2;
for (int i = 0; i < numsSize; i++) {
count = 0; // 每次外层循环开始时重置计数器
for (int j = 0; j < numsSize; j++) {
if (nums[i] == nums[j]) {
count++;
}
if (count > times) {
return nums[i];
}
}
}
return 0;
}