在屏幕上打印杨辉三角。
1
1 1
1 2 1
1 3 3 1
……........
public class Main {
//这是一个main方法,是程序的入口:
public static void main(String[] args) {
int[][] arr = new int[10][10];
int i = 0;
int j = 0;
for (i = 0; i < 10; i++) {
for (j = 0; j <= i; j++) {
if (i == j) {
arr[i][j] = 1;
}
if (j == 0) {
arr[i][j] = 1;
}
if (i >= 2 && j >= 1) {
arr[i][j] = arr[i - 1][j] + arr[i - 1][j - 1];
}
}
}
for (i = 0; i < 10; i++) {
for (j = 0; j <= i; j++) {
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
}
}
https://leetcode.cn/problems/missing-number-lcci/description/?envType=list&envId=OoMH8xH5
数组
nums
包含从0
到n
的所有整数,但其中缺了一个。请编写代码找出那个缺失的整数。你有办法在O(n)时间内完成吗?注意:本题相对书上原题稍作改动
示例 1:
输入:[3,0,1] 输出:2示例 2:
输入:[9,6,4,2,3,5,7,0,1] 输出:8
class Solution {
/*
解题思路:
直接将数组中所有元素之和sum,然后求出1~N的前N项和-sum即可
时间复杂度O(N),空间复杂度:O(1)
缺陷:如果数组中元素比较多,相加完成之后容易溢出
*/
public int missingNumber1(int[] nums) {
int sum = 0;
for(int i = 0; i < nums.length; ++i){
sum += nums[i];
}
return ((1+nums.length)*nums.length)/2 - sum;
}
/*
解题思路:
采用异或的方式解决,因为两个相同的数字异或的结果是0
因此:将0~N之间的数字,与数组中的每个数字异或,
最终的结果就是丢失的数字
*/
public int missingNumber2(int[] nums) {
int data = 0;
for(int i = 0; i < nums.length; ++i){
data ^= nums[i];
data ^= i;
}
data ^= nums.length;
return data;
}
/*
解题思路:
将1~N之间的数组相加,然后减去nums数组中的每个数字
*/
public int missingNumber(int[] nums) {
int data = nums.length;
for(int i = 0; i < nums.length; ++i){
data = data - nums[i] + i;
}
return data;
}
}
https://leetcode.cn/problems/remove-duplicates-from-sorted-array/description/?envType=list&envId=OoMH8xH5
给你一个 升序排列 的数组
nums
,请你** 原地 (opens new window)** 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。由于在某些语言中不能改变数组的长度,所以必须将结果放在数组nums的第一部分。更规范地说,如果在删除重复项之后有
k
个元素,那么nums
的前k
个元素应该保存最终结果。将最终结果插入
nums
的前k
个位置后返回k
。不要使用额外的空间,你必须在 **原地 (opens new window)**修改输入数组并在使用 O(1) 额外空间的条件下完成。
判题标准:
系统会用下面的代码来测试你的题解:
int[] nums = [...]; // 输入数组 int[] expectedNums = [...]; // 长度正确的期望答案 int k = removeDuplicates(nums); // 调用 assert k == expectedNums.length; for (int i = 0; i < k; i++) { assert nums[i] == expectedNums[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 。不需要考虑数组中超出新长度后面的元素。
提示:
1 <= nums.length <= 3 * 10^4
-10^4 <= nums[i] <= 10^4
nums
已按 升序 排列
/**
解题思路:双指针思想 一个指针对数组遍历,一个指针指向即将被赋值的位置
1.遍历数组中的每个元素
2.当前被遍历的元素跟上一个元素进行比较,如果当前元素跟上个元素不同,那么就保存,相同就跳过。
*/
class Solution {
public int removeDuplicates(int[] nums) {
//指针 j 指向即将被赋值的位置
int j = 0;
//指针 i 进行数组遍历
for (int i = 0; i < nums.length; i++) {
if (i == 0 || nums[i] != nums[i - 1]) {
//i == 0说明是第一个元素,第一个元素要先赋值,因为它前面没有元素,每次遍历的时候要比较当前元素和它上一个元素的值,如果不相等,说明不重复,就需要赋值
nums[j] = nums[i];
//一旦赋值了说明此时的nums[j]上有元素了,有元素就要让j向下一个位置移动,因为j是指向即将被赋值的位置,相当于占个位置
j++;
}
}
//遍历完成之后,直接返回j即可,数组索引的特性,索引代表几就说明前面有几个元素
return j;
}
}
https://leetcode.cn/problems/remove-element/description/?envType=list&envId=OoMH8xH5
给你一个数组
nums
和一个值val
,你需要 原地 (opens new window)移除所有数值等于val
的元素,并返回移除后数组的新长度。不要使用额外的数组空间,你必须仅使用
O(1)
额外空间并 **原地 (opens new window)**修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
说明:
为什么返回数值是整数,但输出的答案是数组呢?
请注意,输入数组是以**「引用」**方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。
你可以想象内部操作如下:
// 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。注意这五个元素可为任意顺序。你不需要考虑数组中超出新长度后面的元素。
提示:
0 <= nums.length <= 100
0 <= nums[i] <= 50
0 <= val <= 100
class Solution {
// public int removeElement(int[] nums, int val) {
// /*
// 1. 从前往后遍历nums,找到val第一次出现的位置
// 2. 将val之后的所有元素整体往前搬移,即删除该val
// 3. nums中有效元素个数减少一个
// 循环进行上述操作,直到nums中所有值为val的元素全部删除完
// 时间复杂度:O(N^2) 空间复杂度:O(1)
// */
// int size = nums.length;
// int i = 0;
// while(true){
// // 1. 在nums中找val的位置
// for(i = 0; i < size; ++i){
// if(nums[i] == val){
// break;
// }
// }
// if(i == size){
// // nums中没有发现值为val的元素,直接跳出while
// break;
// }
// // 2. 将i位置之后所有元素整体往前搬移一个位置
// for(int pos = i+1; pos < size; ++pos){
// nums[pos-1] = nums[pos];
// }
// // 注意:一趟之后size一定要减去1,因为删除了一个val
// size--;
// }
// return size;
// }
/*
解题思路:
1. 创建一个长度与nums相同的数组ret
2. 遍历nums,将nums中所有与val不同的元素搬移到ret中
3. 将ret中所有元素拷贝回nums中
时间复杂度: O(N) 空间复杂度: O(N)
*/
// public int removeElement(int[] nums, int val) {
// int[] ret = new int[nums.length];
// int size = 0;
// for(int i = 0; i < nums.length; ++i){
// if(nums[i] != val){
// ret[size++] = nums[i];
// }
// }
// System.arraycopy(ret, 0, nums, 0, size);
// return size;
// }
/*
解题思路:
1. 设置一个变量count,用来记录nums中值等于val的元素的个数
2. 遍历nums数组,对于每个元素进行如下操作:
a. 如果num[i]等于val,说明值为val的元素出现了一次,count++
b. 如果nums[i]不等于元素,将nums[i]往前搬移count个位置
因为nums[i]元素之前出现过count个值等于val的元素,已经被删除了
因此此处需要将nums[i]往前搬移
3. 返回删除之后新数组中有效元素个数
时间复杂度:O(N) 空间复杂度:O(1)
*/
// public int removeElement(int[] nums, int val) {
// int count = 0;
// for(int i = 0; i < nums.length; ++i){
// if(nums[i] == val){
// count++;
// }else{
// nums[i - count] = nums[i];
// }
// }
// return nums.length - count;
// }
/**
解题思路:双指针思想
1.遍历数组中的每个元素
2.遍历的元素跟val作比较,如果不等于val就保留,等于val就跳过
*/
public int removeElement(int[] nums, int val) {
//指针 j 指向即将被赋值的位置
int j = 0;
//指针 i 遍历数组
for (int i = 0; i < nums.length; i++) {
//进行筛选,如果每次遍历到的元素的值跟val不一样,就有资格留下来进行赋值
if (nums[i] != val) {
nums[j] = nums[i];
//一旦赋值了说明此时的nums[j]上有元素了,有元素就要让j向下一个位置移动,因为j是指向即将被赋值的位置,相当于占个位置
j++;
}
}
//遍历完成之后,直接返回j即可,数组索引的特性,索引代表几就说明前面有几个元素
return j;
}
}
https://leetcode.cn/problems/move-zeroes/description/
给定一个数组
nums
,编写一个函数将所有0
移动到数组的末尾,同时保持非零元素的相对顺序。请注意 ,必须在不复制数组的情况下原地对数组进行操作。
示例 1:
输入: nums = [0,1,0,3,12] 输出: [1,3,12,0,0]
示例 2:
输入: nums = [0] 输出: [0]
提示:
1 <= nums.length <= 10^4
-2^31 <= nums[i] <= 2^31 - 1
class Solution {
/**
解题思路:双指针
1.指针 i 遍历数组的每个元素
2.遍历的元素如果非 0,就赋值且让指针 j 向后移动,为 0 就跳过
3.因为有几个非 0 的元素,j就会向后移动几个位置,即 j 前面的都是非 0 元素,j指向所有为 0 元素的第一个位置,后面都是为 0 的元素
时间复杂度:O(n),其中 n 为序列长度。每个位置至多被遍历两次。
空间复杂度:O(1)。只需要常数的空间存放若干变量。
*/
public void moveZeroes(int[] nums) {
// 指针 j 指向经过一系列操作后数组中所有为 0 元素的第一个位置上
// 一开始默认在索引为 0 的位置
int j = 0;
// 指针 i 从头到尾遍历数组
// 遍历完毕之后,j 指向了一个为 0 的元素,或者如果数组中不存在 0 ,就和 i 一样,超过了数组的范围
for (int i = 0; i < nums.length; i++) {
// 在遍历过程中,如果发现访问的元素是非 0 元素
// 说明 j 不在正确的位置上,需要向后移动,寻找合适的位置
if (nums[i] != 0) {
// 这个时候,原先 j 的值需要被 i 的值覆盖
nums[j] = nums[i];
// j 需要向后移动,寻找合适的位置
j++;
}
}
// 接下来,只需要把 j 及其后面所有的元素都设置为 0 就行,因为 j 指向是所有为 0 元素的第一个位置上
for (int i = j; i < nums.length; i++) {
// 都设置为 0
nums[i] = 0;
}
}
}
给定一个二进制数组
nums
, 计算其中最大连续1
的个数。示例 1:
输入:nums = [1,1,0,1,1,1] 输出:3 解释:开头的两位和最后的三位都是连续 1 ,所以最大连续 1 的个数是 3.
示例 2:
输入:nums = [1,0,1,1,0,1] 输出:2
提示:
1 <= nums.length <= 10^5
nums[i]
不是0
就是1
.
public class Solution {
public int findMaxConsecutiveOnes(int[] nums) {
// 最后一个 0 所在的索引位置
int lastZero = -1;
// 结果
int ans = 0;
// 从左到右访问数组 nums
for (int i = 0; i < nums.length; i++) {
// 1、当前元素为 0 ,更新 lastZero
if (nums[i] == 0) {
lastZero = i;
}
// 2、否则说明当前元素为 1
else {
// 通过 lastZero 可以获取当前元素距离最前面的 1 的个数
// 对比之前的 ans ,更新获取最大值
ans = Math.max(ans, i - lastZero);
}
}
// 返回结果
return ans;
}
}
题目内容:
实现一个方法 transform, 以数组为参数, 循环将数组中的每个元素 乘以 2 , 并设置到对应的数组元素上. 例如 原数组为 {1, 2, 3}, 修改之后为 {2, 4, 6}将数组里面的值 扩大2倍,有两种方式,一种是在自己本身上进行扩大,一种是新的数组中扩大。
/*import java.util.Arrays;
public class OnlineTest {
public static int[] transFrom(int[] a) {
for (int i = 0; i < a.length; i++) {
a[i] *= 2;
}
return a;
}
//这是一个main方法,是程序的入口:
public static void main(String[] args) {
int[] array = {1, 2, 3};
int[] ret = transFrom(array); //创建了一个变量和array同时指向array指向的那个数组,没创建新数组,但是多了个变量。
System.out.println(Arrays.toString(ret));
}
}*/
/*
import java.util.Arrays;
public class OnlineTest {
public static void transFrom(int[] a) {
for (int i = 0; i < a.length; i++) {
a[i] *= 2;
}
}//无需返回值,直接在原数组上扩大二倍
//这是一个main方法,是程序的入口:
public static void main(String[] args) {
int[] array = {1, 2, 3};
transFrom(array);
System.out.println(Arrays.toString(array));
}
}*/
import java.util.Arrays;
public class OnlineTest {
public static int[] transFrom(int[] a) {
int[] tmpArray = new int[a.length];
for (int i = 0; i < a.length; i++) {
tmpArray[i] = a[i] * 2;
}
return tmpArray;
}//返回新的数组的地址,两个不同的数组空间
//这是一个main方法,是程序的入口:
public static void main(String[] args) {
int[] array = {1, 2, 3};
int[] ret = transFrom(array);
System.out.println(Arrays.toString(ret));
}
}
题目内容:
调整数组顺序使得奇数位于偶数之前。调整之后,不关心大小顺序。如数组:[1,2,3,4,5,6]
调整后可能是:[1, 5, 3, 4, 2, 6]
import java.util.Arrays;
public class OnlineTest {
public static void fun(int[] array) {
//在数组的两端的下标分别同时向中间逼近,前提:left < right 左边:如果是奇数就让指针++,右边:如果是偶数就让指针--,
int left = 0;
int right = array.length - 1;
while (left < right) {
while (left < right && array[left] % 2 != 0) {//奇数 如果全是奇数,left一直++,left>right,下标不准确,交换会出现错误
left++;
}
while (left < right && array[right] % 2 == 0) {//偶数 如果全是偶数,right一直--,right
题目内容:
给定一个有序整型数组, 实现二分查找
import java.util.Arrays;
public class OnlineTest {
public static int myBinarySearch(int[] arr, int key) {
int left = 0;
int right = arr.length - 1;
while (left <= right) {
int mid = (left + right) / 2;// 每次中间下标是要发生变化的,要放在循环
if (arr[mid] > key) {//查找的值小于中间值, 说明值在左边, 右下标变化
right = mid - 1;
} else if (arr[mid] < key) {//查找的值大于中间值, 说明值在右边, 左下标变化
left = mid + 1;
} else {
return mid; //找到了,返回下标
}
}
return -1; // 找不到返回-1
}
/*
* 局面
* 外接给我的任务、参数,称为局面
* 经过一定的处理,变成一个新局面,
* */
//递归写法:
public static int binarySearch(int[] arr, int left, int right, int target) {
int midIndex = left + ((right - left) >> 1);
int midValue = arr[midIndex];
//递归调用 出口:找到值,规则:往右走或者往左走
if (target > midValue) {//往右走
return binarySearch(arr, midIndex + 1, right, target);
} else if (target < midValue) {//往左走
return binarySearch(arr, left, midIndex - 1, target);
} else {
return midIndex;
}
}
//这是一个main方法,是程序的入口:
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5};
int ret1 = myBinarySearch(arr, 5);
int ret2 = myBinarySearch(arr, 6);
//递归调用:
int ret3 = binarySearch(arr, 0, 3, 2);//在指定的下标范围查找target
System.out.println(ret1);//4
System.out.println(ret2);//-1
System.out.println(ret3);//1
System.out.println("-----");
Arrays.sort(arr);// 注意:使用二分查找的前提是有序数组!!!
System.out.println(Arrays.binarySearch(arr, 5));//4
System.out.println(Arrays.binarySearch(arr, 6)); //-6 如果查找的数 > 最后一个元素,返回的值是:-(arr.length+1)
}
}
题目内容:
给定一个整型数组, 实现冒泡排序(升序排序)
进一步优化,当数据在排序过程当中有序了,会在某一趟排序后,发现数据没有交换。
所以,每一趟排序完,都去检查是否发生了交换,没有交换证明数据已近有序,不需要再进行剩余趟数的排序了。
import java.util.Arrays;
public class OnlineTest {
//如果数很多,意味着要比较很多趟,假如在前几趟就已经有序了,后面很多趟都不需要继续比较了,再比较就是浪费
//假如第一趟有序了,第二趟没有发生交换才能说明当前数组有序
public static void bubbleSort(int[] array) {
for (int i = 0; i < array.length - 1; i++) { //有n个数,要比较n-1趟
boolean flag = false; //每一趟都要有flag,因为不知道具体在哪一趟会有序
for (int j = 0; j < array.length - 1 - i; j++) { //每趟只需比较n - 1 - i个数,不需要n-1个数,因为每趟都会找出一个最大值往右边放,比较的个数就会少一个
if (array[j] > array[j + 1]) {
int tmp = array[j];
array[j] = array[j + 1];
array[j + 1] = tmp;
flag = true; //此趟发生了交换
}
if (flag == false) {//说明此趟没有进行交换,可判断当前数组有序,停止后面的比较
return;
}
}
}
}
//这是一个main方法,是程序的入口:
public static void main(String[] args) {
int[] array = {1, 3, 5, 7, 9, 2, 4, 6, 8, 10};
bubbleSort(array);
System.out.println(Arrays.toString(array));
}
}
题目内容:
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个整数,并返回它们的数组下标。你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
示例 1:
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
本题最重要的一句话:假设每种输入只会对应一个答案
也就意味着不会有多个答案,暴力求解就是挨个匹配查找即可
如果想提升效率,需要用到哈希表来解答
import java.util.Arrays;
public class OnlineTest {
public static int[] findTarget(int[] nums, int target) {
int[] ret = {-1, -1};
//int[] ret = new int[2];
for (int i = 0; i < nums.length; i++) {//遍历这个数组
for (int j = i + 1; j < nums.length; j++) {//从第二个数开始遍历
if (nums[i] + nums[j] == target) {
/*ret = new int[]{i, j};*/
ret[0] = i;
ret[1] = j;
return ret;
}
}
}
return ret;
}
//这是一个main方法,是程序的入口:
public static void main(String[] args) {
int[] nums = {2, 7, 11, 15};
int[] ret = findTarget(nums, 18);
System.out.println(Arrays.toString(ret));
}
}
题目内容:
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。示例 1:
输入: [2,2,1]
输出: 1
示例 2:输入: [4,1,2,1,2]
输出: 4本题主要考察运算符:异或。
异或的特点是:
1、n ^ n = 0;即两个相同的数字异或是0
2、0 ^ n = n;即0和任何数字进行异或,结果就是那个任何数字。
public int singleNumber(int[] nums) {
// 用异或运算的性质可以巧妙的解决这个问题,因为数组中只有一个数字出现一次
// 则其他出现两次的数字用异或运算后都是0,最终整个数组异或运算的结果即为所求。
int ret = 0;
for (int i : nums) {
ret ^= i;
}
return ret;
}
public class OnlineTest {
//0 ^ x = x x ^ x = 0 异或有交换律,所以最终会剩下只出现一次的数字
public static int findNum(int[] array) {
int ret = array[0];
for (int i = 1; i < array.length; i++) {
ret ^= array[i];
}
return ret;
}
//这是一个main方法,是程序的入口:
public static void main(String[] args) {
int[] array = {2, 2, 1};
int ret = findNum(array);
System.out.println(ret);
}
}
题目内容:
给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
示例 1:
输入:[3,2,3]
输出:3
示例 2:输入:[2,2,1,1,1,2,2]
输出:2常规办法:数组中出现次数超过一半的数字,一定是排好序之后,中间位置的数字。
import java.util.Arrays;
public class OnlineTest {
public static int findMoreNum1(int[] array) {
//先进行排序,因为是找多数元素:在数组中出现次数>n/2的元素,所以数组中间的那个数一定是多数元素
Arrays.sort(array);
return array[array.length / 2];
}
public static int findMoreNum2(int[] array) {
int count = 0;
int tmp = array[0];
for (int i = 0; i < array.length; i++) {
if (array[i] == tmp) {
count++;
} else if (array[i] != tmp) {
count--;
} /*else if (count == 0) { //这儿必须是if,如果一直array[i] != tmp, count--之后等于-1,没有执行此语句了
count++;
tmp = array[i];
}*/
if (count == 0) {
//2 2 3 3 2,当count == 0时,说明此时已经遍历到第2个3了,此时count++之后=1,tmp = 3 i = 3
//最后一次遍历,i = 4,array[4] = 2 != tmp = 3,count--之后=0,走if(count == 0)这个分支,count又++之后=1
//此时赋值给tmp = array[4] = 2,即出现次数最多的那个数
//总结:哪个数让count == 0了,下次计数就从它开始。
count++;
tmp = array[i];
}
}
return tmp;
}
//这是一个main方法,是程序的入口:
public static void main(String[] args) {
int[] array = {2, 2, 3, 3, 2};
int ret1 = findMoreNum1(array);
int ret2 = findMoreNum2(array);
System.out.println(ret1);
System.out.println("---");
System.out.println(ret2);
}
}
题目内容:
给你一个整数数组 arr,请你判断数组中是否存在连续三个元素都是奇数的情况:如果存在,请返回 true ;否则,返回 false 。示例 1:
输入:arr = [2,6,4,1]
输出:false
解释:不存在连续三个元素都是奇数的情况。
示例 2:
输入:arr = [1,2,34,3,4,5,7,23,12]
输出:true
解释:存在连续三个元素都是奇数的情况,即 [5,7,23] 。
数字是连续出现的,所以我们只需要定义一个计数器,如果连续出现的次数超过3,则返回true。
import java.util.Arrays;
public class OnlineTest {
public static boolean fun(int[] array) {
int count = 0;
for (int i = 0; i < array.length; i++) {
if (array[i] % 2 != 0) {
count++;
if (count == 3) {
return true;
}
} else {
count = 0;
}
}
return false;
}
//这是一个main方法,是程序的入口:
public static void main(String[] args) {
int[] array = {1,3,5,2,4,6};
boolean ret = fun(array);
System.out.println(ret);
}
}
给你两个按 非递减顺序 排列的整数数组
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 中。提示:
nums1.length == m + n
nums2.length == n
0 <= m, n <= 200
1 <= m + n <= 200
-109 <= nums1[i], nums2[j] <= 109
class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
int i = m - 1;
int j = n - 1;
int k = m + n - 1;
//两个数组都有元素
while (i >= 0 && j >= 0) {
if (nums1[i] <= nums2[j]) {
nums1[k] = nums2[j];
j--;
k--;
} else {
nums1[k] = nums1[i];
i--;
k--;
}
}
//nums1走完了,nums2里面还有元素没拷贝到nums1
while (j >= 0) {
nums1[k] = nums2[j];
j--;
k--;
}
}
}
https://leetcode.cn/problems/rotate-array/description/?envType=list&envId=OoMH8xH5
给定一个整数数组
nums
,将数组中的元素向右轮转k
个位置,其中k
是非负数。示例 1:
输入: nums = [1,2,3,4,5,6,7], k = 3 输出:[5,6,7,1,2,3,4]
解释: 向右轮转 1 步:[7,1,2,3,4,5,6]
向右轮转 2 步:[6,7,1,2,3,4,5]
向右轮转 3 步:[5,6,7,1,2,3,4]
示例 2:
输入:nums = [-1,-100,3,99], k = 2 输出:[3,99,-1,-100] 解释: 向右轮转 1 步: [99,-1,-100,3] 向右轮转 2 步: [3,99,-1,-100]提示:
1 <= nums.length <= 105
-231 <= nums[i] <= 231 - 1
0 <= k <= 105
/*
解题思路:
按照题目所说,进行k次旋转,每次旋转移动一个字符
注意:k如果超过nums的长度时,对k取模
时间复杂度: O(KN)
思路没有问题,但是会时间复杂度会超
*/
/*
class Solution {
public void rotate(int[] nums, int k) {
k %= nums.length;
for(int i = 0; i < k; ++i){
// 将数组中前n-1个元素整体往后搬移一个位置
int last = nums[nums.length-1];
for(int j = nums.length-1; j >= 1; --j){
nums[j] = nums[j-1];
}
// 将搬移前最后一个元素放到数组0号位置
nums[0] = last;
}
}
}
*/
/*
解题思路:使用三次逆转法,让数组旋转k次
1. 整体逆置
2. 逆转子数组[0, k - 1]
3. 逆转子数组[k, size - 1]
*/
class Solution {
void rotate(int[] nums, int left, int right){
while(left < right){
int temp = nums[left];
nums[left] = nums[right];
nums[right] = temp;
left++;
right--;
}
}
public void rotate(int[] nums, int k) {
k %= nums.length;
rotate(nums, 0, nums.length-1);
rotate(nums, 0, k-1);
rotate(nums, k, nums.length-1);
}
}