booldeleteMin(vector<int>& nums, int& val){ if (nums.empty()) { returnfalse; } int minVal = INT32_MAX, minIdx = 0; for (int i = 0; i < nums.size(); ++i) { if (minVal > nums[i]) { minVal = nums[i]; minIdx = i; } } nums[minIdx] = nums.back(); val = minVal; returntrue; }
逆置顺序表
题目描述
设计一个高效算法,将顺序表 L 的所有元素逆置,要求算法的空间复杂度为 O(1).
解题代码
1 2 3 4 5 6
voidreverseList(vector<int>& nums){ int left = 0, right = nums.size() - 1; while (left < right) { swap(nums[left++], nums[right--]); } }
删除特定值的元素
题目描述
对长度为 n 的顺序表 L,编写一个时间复杂度为 O(n)、空间复杂度为 O(1) 的算法,该算法删除线性表中的所有值为 x 的数据元素。
解题代码
1 2 3 4 5 6 7 8
voiddeleteX(vector<int>& nums, int x){ int n = nums.size(), xCnt = 0; // 记录当前遍历位置之前x的出现次数 for (int i = 0; i < n; ++i) { nums[i - xCnt] = nums[i]; xCnt += nums[i] == x; } nums.erase(nums.begin() + n - xCnt, nums.end()); // 删除冗余元素 }
删除特定区间内的元素
题目描述
从有序顺序表中删除其值在给定值 s 和 t 之间(要求 s < t)的所有元素,若 s 或 t 不合理或者顺序表为空,则显示错误信息并退出运行。
解题代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
booldeleteInterval(vector<int>& nums, int s, int t){ if (s >= t || nums.empty()) { returnfalse; } int n = nums.size(); int left = 0, right = n - 1; while (nums[left] < s) { // 找到首个不小于s的元素 ++left; } while (nums[right] > t) { // 找到首个不大于t的元素 --right; } int length = right - left + 1; for (int i = left; i + length < n; ++i) { nums[i] = nums[i + length]; // 移动元素 } nums.erase(nums.begin() + n - length, nums.end()); returntrue; }
删除重复元素
题目描述
从有序顺序表中删除所有值重复的元素,使表中所有元素的值均不同。
解题代码
1 2 3 4 5 6 7 8 9 10 11 12
voiddeleteRedundancy(vector<int>& nums){ int reCnt = 0, n = nums.size(); for (int i = 1; i < n; ++i) { if (nums[i] == nums[i - 1]) { ++reCnt; } else { nums[i - reCnt] = nums[i]; } } nums.erase(nums.begin() + n - reCnt, nums.end()); }
voidswapList(vector<int>& nums, int m, int n){ for (int i = 0, j = m + n - 1; i < j; ++i, --j) { swap(nums[i], nums[j]); // 整体逆置 } for (int i = 0, j = n - 1; i < j; ++i, --j) { swap(nums[i], nums[j]); // 前n个元素逆置 } for (int i = n, j = m + n - 1; i < j; ++i, --j) { swap(nums[i], nums[j]); // 后m个元素逆置 } }
查找有序表中的特定值元素
题目描述
线性表(a1, a2, …, an)中的元素递增有序且按顺序存储在计算机内。要求设计一个算法,完成用最少时间在表中查找值为 x 的元素,若找到,则将其与后继元素位置相交换。若找不到,则将其插入表中并使表中元素仍然递增有序。
解题代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
voidsearchX(vector<int>& nums, int x){ int left = 0, right = nums.size() - 1; while (left <= right) { int mid = (left + right) / 2; // 二分查找 if (x == nums[mid]) { if (mid != nums.size() - 1) { swap(nums[mid], nums[mid + 1]); } return; } elseif (x < nums[mid]) { right = mid - 1; } else { left = mid + 1; } } nums.insert(nums.begin() + left, x); // 查找失败,插入x }
已知一个整数序列 A = (a0, a1, …, an - 1),其中 0 <= ai < n(0 <= i < n)。若存在 ap1 = ap2 = … = apm = x 且 m > n / 2(0 <= pk < n, 1 <= k <= m),则称 x 为 A 的主元素。例如 A = (0, 5, 5, 3, 5, 7, 5, 5),则 5 为主元素;又如 A = (0, 5, 5, 3, 5, 1, 5, 7)。则 A 中没有主元素。假设 A 中的 n 个元素保存在一个一维数组中,请设计一个尽可能高效的算法,找出 A 的主元素。若存在主元素,则输出该元素;否则输出 -1。
intgetMinPositive(vector<int>& nums){ int n = nums.size(); vector<bool> numSet(n, false); for (int i = 0; i < n; ++i) { if (nums[i] > 0 && nums[i] <= n) { numSet[nums[i] - 1] = true; } } for (int i = 0; i < n; ++i) { if (!numSet[i]) { return i + 1; } } return n + 1; }