计算元素移动次数
- 在长度为 n 的顺序表下标为 i 的位置前插入一个元素(1 ≤ i ≤ n+1),元素的移动次数为( )
A.n - i + 1
B.n - i
C.i
D.i - 1
答案:B
即:把[i, n - 1]区间的元素全部向后移动一次,故移动的次数为n - 1 - i + 1。
ArrayList类
2.对于类java.util.ArrayList,哪个语句是正确的?
A.ArrayList中的元素是有序的。
B.ArrayList中的元素保证是可变的。
C.ArrayList中的元素保证是唯一的。
D.使用唯一密钥访问ArrayList中的元素。
A错误:ArrayList中的元素不一定有序,ArrayList没有要求里面的元素必须有序,可能有序也可能不有序
B正确:ArrayList中的元素可以通过下标修改
C错误:ArrayList中的元素每一要求必须要唯一,可以唯一也可以重复
D错误:ArrayList中的元素是通过下标访问的,而不是通过key
故正确应该选择B
杨辉三角
public class Solution {
public List<List<Integer>> generate(int numRows) {
List<List<Integer>>ret=new ArrayList<>();
List<Integer>row=new ArrayList<>();
row.add(1);
ret.add(row);
for (int i=1;i<numRows;i++){
List<Integer>preRow=ret.get(i-1);//前一行
List<Integer>curRow=new ArrayList<>();
curRow.add(1); //顺序表的第一个1
//中间curRow list的赋值
//j活动的范围
for(int j=1;j<i;j++){
int x=preRow.get(j)+preRow.get(j-1);
curRow.add(x);
}
curRow.add(1);//顺序表的最后一个1
ret.add(curRow);
}
return ret;
}
}
解题思路:
仔细观察发现杨辉三角类似于一个二维数组,第0列和对角线上的元素全部都是1
其余位置都是上一行正对元素 与 上一行正对元素的前一个元素之和
先确定第一个数组和最后一个数组的元素都为1,中间的数组用循环嵌套赋值。
合并两个有序数组
import java.util.Arrays;
public class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
for(int i=-0;i!=n;++i){
//将数组nums2的元素写入nums1
nums1[m+i]=nums2[i];
}
Arrays.sort(nums1);
}
}
先合并,然后用java自带sort方法进行删重。
class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
// end1、end2:分别标记nums1 和 nums2最后一个有效元素位置
// end标记nums1的末尾,因为nums1和nums2中的元素从后往前往nums1中存放
// ,否则会存在数据覆盖
int end1 = m-1;
int end2 = n-1;
int end = nums1.length-1;
// 从后往前遍历,将num1或者nums2中较大的元素往num1中end位置搬移
// 直到将num1或者num2中有效元素全部搬移完
while(end1 >= 0 && end2 >= 0){
if(nums1[end1] > nums2[end2]){
nums1[end--] = nums1[end1--];
}else{
nums1[end--] = nums2[end2--];
}
}
// 如果nums2中的数据没有搬移完,搬移剩余nums中的元素
while(end2 >= 0){
nums1[end--] = nums2[end2--];
}
// num1中可能有数据没有搬移完,不用管,因为这些元素已经在nums1中了
}
}
解题思路:
1. 从后往前遍历数组,将nums1和nums2中的元素逐个比较
将较大的元素往nums1末尾进行搬移
2. 第一步结束后,nums2中可能会有数据没有搬移完,将nums2中剩余的元素逐个搬移到nums1
利用三个逆向指针进行归并。
删除排序数组中的重复项
public int removeDuplicates(int[] nums) {
int n = nums.length;
if (n == 0) {
return 0;
}
int fast = 1, slow = 1;
while (fast < n) {
if (nums[fast] != nums[fast - 1]) {
nums[slow] = nums[fast];
++slow;
}
++fast;
}
return slow;
}
定义两个指针 fast 和 slow 分别为快指针和慢指针,快指针表示遍历数组到达的下标位置,慢指针表示下一个不同元素要填入的下标位置,初始时两个指针都指向下标。
class Solution {
public int removeDuplicates(int[] nums) {
int count = 1; // 标记从前往后遍历时,遇到的不同元素的个数
for(int i = 1; i < nums.length; ++i){
// 注意:count是从前往后遍历时遇到的不同元素的个数
// count-1就是i位置之前最后一个不同元素的位置
// 因此需要将num[i]搬移到nums[count]处
if(nums[count-1] != nums[i]){
nums[count++] = nums[i];
}
}
return count;
}
}
解题思路:
1. 设置一个计数,记录从前往后遍历时遇到的不同元素的个数
由于不同的元素需要往前搬移,那count-1就是前面不同元素
搬移之后,最后一个元素的位置,下一次在遇到不同元素就应该
搬移到count位置
2. 遍历数组,如果nums[i]与nums[count-1]不等,就将nums[i]搬移
到nums[count]位置,不同元素多了一个,给count++
3. 循环结束后,返回count 。