今天看了一些刷题笔记和大神的刷题方法,决定按照分类来刷题,第一个内容就是数组,leetcode上共有342个数组题目,有挑选性地刷一段时间,循序渐进吧。
以下小题均为leetbook中数组类算法的全部题目,以此为我这段时间数组训练的开端叭!
leetbook数组类算法:
1.移动零
解题思想:
将所有0移动到数组末尾,也就是把不为0的数依次移动到前面来,最后将空余出来的位置赋值为0.需要两个计数器,第一个计数器用来记录0的个数,第二个计数器用来记录非0的个数,在一次循环遍历中如果当前值为0,记录0的计数器加1,为后续给其赋值0作条件,如果当前值不为0,则依次从前面往后放到数组里去。索引为计数器。
源代码:
class Solution {
public void moveZeroes(int[] nums) {
int a=0, b=0;
for(int i=0; i<nums.length; i++){
if(nums[i] == 0){
a++;
}
else{
nums[b] = nums[i];
b++;
}
}
for(int i=nums.length-1; a!=0; i--,a--){
nums[i] = 0;
}
}
}
2.移除元素
解题思想:
由于要对数组原地修改,所以采用双指针,一个指向数组头部,一个指向数组尾部,对数组进行一次遍历,当头部指针指向要去掉的值时,用尾部指针的值覆盖掉(因为是引用所以可以实现直接覆盖)。注意返回值为头部指针!!!
源代码:
class Solution {
public int removeElement(int[] nums, int val) {
int i=0, j=nums.length;
int num = 0;
while(i<j){
if(nums[i]==val){
nums[i] = nums[j-1];
j--;
}
else{
i++;
}
}
return i;
}
}
3.删除排序数组中的重复项
解题思路:
(借鉴其他大佬的算法思想)原地删除重复元素,还是借助双指针,指向两个相邻的索引值,当这两个值相等则后者加1,若不等则将后者移到前者的后一位。返回值不可以是j,只能是i+1(第一次我写的j,输出的数组值是错的),原因是j在移动过程中可能早就跑的很靠后了,和数组元素个数没有一丁点关系QAQ。
感叹一波,java中原地修改数组真的好神奇~
源代码:
class Solution {
public int removeDuplicates(int[] nums) {
int i=0, j=1;
while(j<nums.length){
if(nums[i]==nums[j]){
j++;
}
else{
nums[i+1] = nums[j];
i++;
j++;
}
}
return i+1;
}
}
3.删除排序数组中的重复项II
解题思路:
本题和上一题相同都是要按照要求来原地移除元素的,只是上个一个题目中要求每个元素只保存一个,这个题目中要求保存≤2个。依旧是借鉴了网上大佬的思路:往常来说移除元素都是双指针,如果指针所指向的两个元素相同那么做出相应的操作。但本题目的思路反其道而行之,双指针指向的两个元素不相同来操作,双指针指向的是隔了1个索引的元素,如果相等那就向后移动,如果不相等说明已经有连续两个数或者一个数满足题目要求了,这种情况下要把不相等的后面那个数移动到前一位。这样遍历一遍数组即可得到新的满足要求的数组了。
源代码:
class Solution {
public int removeDuplicates(int[] nums) {
int i=2, j=2;
while(j<nums.length){
if(nums[i-2]==nums[j]){
j++;
}
else{
nums[i]=nums[j];
i++;
j++;
}
}
return i;
}
}