26. 删除有序数组中的重复项
给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
说明:
为什么返回数值是整数,但输出的答案是数组呢?
请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。
你可以想象内部操作如下: // nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝 int len = removeDuplicates(nums);
// 在函数里修改输入数组对于调用者是可见的。 // 根据你的函数返回的长度, 它会打印出数组中 该长度范围内 的所有元素。
for (int i = 0; i < len; i++) {
print(nums[i]); }
示例 1:
输入:nums = [1,1,2] 输出:2, nums = [1,2] 解释:函数应该返回新的长度 2 ,并且原数组 nums
的前两个元素被修改为 1, 2 。不需要考虑数组中超出新长度后面的元素。
示例 2:
输入:nums = [0,0,1,1,1,2,2,3,3,4] 输出:5, nums = [0,1,2,3,4] 解释:函数应该返回新的长度
5 , 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4 。不需要考虑数组中超出新长度后面的元素。
public static void main(String[] args) {
int[] nums = new int[]{0, 0, 1, 1, 1, 2, 2, 3, 3, 4};
System.out.println(removeDuplicates(nums));
}
public static int removeDuplicates(int[] nums) {
if (null == nums || nums.length == 0) {
return 0;
}
if (nums.length == 1) {
return 1;
}
//定义2个指针
int fast = 1, slow = 1;
while (fast < nums.length) {
if (nums[fast] != nums[fast - 1]) {
//值复制
nums[slow] = nums[fast];
++slow;
}
++fast;
}
return slow;
}
链接:https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array
27. 移除元素
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
说明:
为什么返回数值是整数,但输出的答案是数组呢?
请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。
你可以想象内部操作如下:
// nums 是以“引用”方式传递的。也就是说,不对实参作任何拷贝
int len = removeElement(nums, val);
// 在函数里修改输入数组对于调用者是可见的。 // 根据你的函数返回的长度, 它会打印出数组中 该长度范围内 的所有元素。
for (int i = 0; i < len; i++) {
print(nums[i]); }
示例 1:
输入:nums = [3,2,2,3], val = 3 输出:2, nums = [2,2] 解释:函数应该返回新的长度 2, 并且
nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。例如,函数返回的新长度为 2 ,而 nums =
[2,2,3,3] 或 nums = [2,2,0,0],也会被视作正确答案。
示例 2:
输入:nums = [0,1,2,2,3,0,4,2], val = 2 输出:5, nums = [0,1,4,0,3]
解释:函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0,
4。注意这五个元素可为任意顺序。你不需要考虑数组中超出新长度后面的元素。
public static void main(String[] args) {
int[] nums = new int[]{3, 2, 2, 3};
int val = 3;
int count = removeElement1(nums, val);
System.out.println(count + "长度");
for (int i = 0; i < count; i++) {
System.out.println(nums[i]);
}
}
/**
* 官解
* @param nums
* @param val
* @return
*/
public static int removeElement1(int[] nums, int val) {
int n = nums.length;
int left = 0;
for (int right = 0; right < n; right++) {
if (nums[right] != val) {
nums[left] = nums[right];
left++;
}
}
return left;
}
public static int removeElement(int[] nums, int val) {
if (0 == nums.length) {
return 0;
}
if (nums.length == 1) {
return nums[0] == val ? 0 : 1;
}
int count = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] == val) {
++count;
nums[i] = 0;
}
}
count = nums.length - count;
for (int i = 0; i < nums.length; i++) {
for (int j = i + 1; j < nums.length; j++) {
if (nums[j] > nums[i]) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
}
return count;
}
链接:https://leetcode-cn.com/problems/remove-element
35. 搜索插入位置
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
你可以假设数组中无重复元素。
示例 1:
输入: [1,3,5,6], 5 输出: 2
示例 2:
输入: [1,3,5,6], 2 输出: 1
示例 3:
输入: [1,3,5,6], 7 输出: 4
示例 4:
输入: [1,3,5,6], 0 输出: 0
public static void main(String[] args) {
int[] nums = new int[]{1,3,5,6};
int target = 7;
System.out.println(searchInsert(nums, target));
}
public static int searchInsert(int[] nums, int target) {
int left = 0, right = nums.length - 1;
while (left <= right) {
int mid = (left + right) / 2;
if (nums[mid] == target) {
return mid;
} else if (nums[mid] > target) {
right = right - 1;
} else {
left = left + 1;
}
}
return left;
}
链接:https://leetcode-cn.com/problems/search-insert-position
53. 最大子序和
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例 1:
输入:nums = [-2,1,-3,4,-1,2,1,-5,4] 输出:6 解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。
示例 2:
输入:nums = [1] 输出:1
示例 3:
输入:nums = [0] 输出:0
示例 4:
输入:nums = [-1] 输出:-1
示例 5:
输入:nums = [-100000] 输出:-100000
public static void main(String[] args) {
int[] nums = new int[]{-2, 1, -3, 4, -1, 2, 1, -5, 4};
System.out.println(maxSubArray1(nums));
}
public static int maxSubArray1(int[] nums) {
int pre = 0, maxAns = nums[0];
for (int x : nums) {
pre = Math.max(pre + x, x);
maxAns = Math.max(maxAns, pre);
}
return maxAns;
}
/**
* 贪心算法
* @param nums
* @return
*/
public static int maxSubArray(int[] nums) {
int max = nums[0], sum = 0;
for (int num : nums) {
//上一次相加的结果大于0,则继续相加
if (sum > 0) {
sum += num;
} else {
//小于0则赋值当前结果
sum = num;
}
//相加完之后的值大于max
if (sum > max) {
max = sum;
}
}
return max;
}
链接:https://leetcode-cn.com/problems/maximum-subarray
66. 加一
给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。
最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。
你可以假设除了整数 0 之外,这个整数不会以零开头。
示例 1:
输入:digits = [1,2,3] 输出:[1,2,4] 解释:输入数组表示数字 123。
示例 2:
输入:digits = [4,3,2,1] 输出:[4,3,2,2] 解释:输入数组表示数字 4321。
示例 3:
输入:digits = [0] 输出:[1]
public static void main(String[] args) {
int[] nums = new int[]{9,9};
for (int i : plusOne(nums)) {
System.out.println(i);
}
}
/**
* 评论大佬
* 根据题意加一,没错就是加一这很重要,因为它是只加一的所以有可能的情况就只有两种:
*
* 除 99 之外的数字加一;
* 数字 99。
* 加一得十进一位个位数为 00 加法运算如不出现进位就运算结束了且进位只会是一。
*
* 所以只需要判断有没有进位并模拟出它的进位方式,如十位数加 11 个位数置为 00,如此循环直到判断没有再进位就退出循环返回结果。
*
* 然后还有一些特殊情况就是当出现 9999、999999 之类的数字时,循环到最后也需要进位,出现这种情况时需要手动将它进一位。
* @param digits
* @return
*/
public static int[] plusOne(int[] digits) {
for (int i = digits.length - 1; i >= 0; i--) {
digits[i]++;
digits[i] = digits[i] % 10;
if (digits[i] != 0) {
return digits;
}
}
digits = new int[digits.length + 1];
digits[0] = 1;
return digits;
}