题外话,个人的博客记录将一些生活和学习笔记记录准备放在个人的博客上,个人的学习是以java为重点+算法+一些工具的使用,学习java的我们可以一起学习,思想的共享是双赢。
个人博客链接
题目一描述: 数组去重
给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
题目分析: 因为要使用O(1)的空间复杂度,就是使用简单的几个变量来辅助完成要求。个人使用了三个指针加一个长度计数的变量(也可以不使用),来进行数组去重,cur指针,指向的是不重复数组的最后一个位置,indexA指针指向的是当前没有遍历的元素,indexB指向的是与indexA相同时的界限,是一个移动指针,每次有重复的元素indexB++;cur与indexA是不相等时更新
数组去重:
class Solution {
public int removeDuplicates(int[] nums) {
if(nums.length == 0) return 0;
//定义一个当前指针,定义一个移动指针,移动指针主要是处理重复元素时使用
int indexA = 0;
int indexB = indexA;
int sum = 1;//用来记录数组长度
int cur = 0;//cur为不重复数组的最后一个位置,每次遇到不一样的元素将cur后一个位置进行替换
for(;indexB<nums.length-1;){
//遍历数组的时候,遇到重复的元素就将移动指针后移
while(indexB<nums.length&&nums[indexB] == nums[indexA]){
indexB++;
}
if(indexB != nums.length){
nums[++cur] = nums[indexB];
sum++;
indexA = indexB;
}
}
return sum;
}
}
补充:之前有一个公司的一道面试题
公司给出了部分程序,就是产生一个随机的数组,让你从中间找出重复的元素以及重复元素的数量。限制时间在二十分钟,这个重复元素的数量有两个,一个是每个元素重复的个数,一个是数组元素中重复元素的个数
private static void arrarFun() {
Random random = new Random();
int[] arr = new int[20];
for (int i = 0; i < 20; i++) {
arr[i] = random.nextInt(10);
System.out.print(arr[i] + ",");
}
System.out.println();
// 输出arr数组中重复元素,重复数量
//......
}
个人的想法是,先将数组排好顺序,然后只需要一个O(n)的时间复杂度+O(1)空间复杂度就可以得到结果。依旧是采用两个指针进行计算。
private static void arrarFun() {
Random random = new Random();
int[] arr = new int[20];
for (int i = 0; i < 20; i++) {
arr[i] = random.nextInt(10);
System.out.print(arr[i] + ",");
}
System.out.println();
// 输出arr数组中重复元素,重复数量
Arrays.sort(arr);
//一个指针指向当前的元素,一个指针是移动指针,一个count记录当前元素重复的个数
int indexA = 0;
int indexB = 0;
int count = 0;
for (; indexA < arr.length - 1;) {
boolean flag = false;
indexB = indexA + 1;
while (indexB < arr.length && arr[indexA] == arr[indexB]) {
if (indexB == indexA + 1)
System.out.print(arr[indexA] + ",");
System.out.print(arr[indexA] + ",");
indexB++;
flag = true;
}
if (flag)
count += indexB - indexA;
indexA = indexB;
}
System.out.println();
System.out.println(count);
}
提交了代码后,看到有人使用HaspMap来进行数组去重,进行了改进,这样就不用对数组进行排序了,记录当前元素以及当前元素的次数。
public static void fun() {
Random random = new Random();
int[] arr = new int[20];
for (int i = 0; i < 20; i++) {
arr[i] = random.nextInt(10);
System.out.print(arr[i] + ",");
}
System.out.println();
// 输出arr数组中重复元素,重复数量
Map<Integer, Integer> map = new HashMap();
for (int i = 0; i < arr.length - 1; i++) {
if (map.containsKey(arr[i])) {
int count = map.get(arr[i]);
count++;
map.put(arr[i], count);
} else {
map.put(arr[i], 1);
}
}
System.out.println(map);
}
题目二描述:
给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1。
题目链接
题目分析:
使用一个窗进行字符串匹配,每次窗向后走的位置是一个,知道匹配或者走到最后的位置。(可以使用KMP算法,自己还不是特别熟悉,因此不做改进)
代码如下:
class Solution {
public int strStr(String haystack, String needle) {
//空串默认匹配
if (needle == null || needle.equals(""))
return 0;
//两个指针指向短串的首位,从长串中截取,如果截取的与目标匹配就可以匹配,相当于窗的一个结构
int l = 0;
int r = needle.length();
//遍历长串
for (; l <= haystack.length() - needle.length();) {
//如果匹配返回窗头位置
if (haystack.substring(l, r).equals(needle)) {
return l;
} else {
l++;
r++;
}
}
return -1;//表示不匹配
}
}