前言
今天健完身,休息了会来实验室做算法题,刚开始没状态,后来还可以。
一、旋转数组
题目:给你一个数组,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。
摘要:数组、向右轮转k个位置、k是非负数;
原思想:我想法很普通,完全是出于代码的逻辑,就是定义一个新数组,然后遍历传入的参数数组,每次遍历使新数组的下标等于参数数组的下标与轮转数k的和,如果和比参数数组要大,说明轮转已经超过了数组的长度,需要在轮转到数组最大长度后重头再来,那么就使得新数组的下标等于参数数组的下标与轮转数k的和再减去参数数组的长度,然后将参数数组的值赋值给新数组;否则,直接将参数数组的值赋值给旧数组;
原代码:
class Solution {
public int[] rotate(int[] nums, int k) {
int j=0;
int m = nums.length;
int[] nums2 = new int[m];
for(int i=0;i<nums.length;i++){
j=i+k;
if(j>nums.length-1){
j=j-nums.length;
nums2[j]=nums[i];
}
else{
nums2[j]=nums[i];
}
}
return nums2;
}
}
问题:
使用了新数组,空间消耗大,方法没有技巧性;
新思想:
1.不使用新数组,设置一个临时变量temp,并且可以用求余数的方法得到新数组的下标,即 (i+k) mod nums.length;
2.数组翻转,当我们将数组的元素向右移动 kk次后,尾部 kmod n个元素会移动至数组头部,其余元素向后移动 kmod n个位置。
该方法为数组的翻转:我们可以先将所有元素翻转,这样尾部的 kmod n 个元素就被移至数组头部,然后我们再翻转 [0, kmod n-1]区间的元素和 [kmod n, n-1] 区间的元素即能得到最后的答案。
对于1思想的新代码:
class Solution {
public void rotate(int[] nums, int k) {
int n = nums.length;
int[] news = Arrays.copyOf(nums,n);
for (int i = 0; i < n; i++) {
nums[(i+k)%n] = news[i];
}
}
}
对于2思想的新代码:
class Solution {
public void rotate(int[] nums, int k) {
k %= nums.length;
reverse(nums, 0, nums.length - 1);
reverse(nums, 0, k - 1);
reverse(nums, k, nums.length - 1);
}
public void reverse(int[] nums, int start, int end) {
while (start < end) {
int temp = nums[start];
nums[start] = nums[end];
nums[end] = temp;
start += 1;
end -= 1;
}
}
}
二、存在重复元素
题目:给你一个整数数组 nums 。如果任一值在数组中出现 至少两次 ,返回 true ;如果数组中每个元素互不相同,返回 false;
摘要:整数数组、任一值出现至少两次返回true、任意元素互不相同返回false;
原想法:
两次遍历,如果第一次遍历的值和第二次遍历的值相等,说明有重复的返回true,如果遍历完都么有值相等的,则返回false;
原代码:
class Solution {
public boolean containsDuplicate(int[] nums) {
int temp;
for(int i=0;i<nums.length;i++){
for(int j=i+1;j<nums.length;j++){
if(nums[i]==nums[j]){
return true;
}
}
}
return false;
}
}
问题:
用了两次循环,时间复杂度高;
新思想:
1.先排序后遍历,排序之后元素都按顺序排列,只需比较前后元素即可;
2.使用集合或者哈希表,创建新的集合或者哈希表,如果插入不成功,则说明有重复的;
对于思想1的新代码:
class Solution {
public boolean containsDuplicate(int[] nums) {
Arrays.sort(nums);
int n = nums.length;
for (int i = 0; i < n - 1; i++) {
if (nums[i] == nums[i + 1]) {
return true;
}
}
return false;
}
}
对于思想2的新代码:
class Solution {
public boolean containsDuplicate(int[] nums) {
Set<Integer> set = new HashSet<Integer>();
for (int x : nums) {
if (!set.add(x)) {
return true;
}
}
return false;
}
}
总结
1.这两道题都做出来了,但么有考虑解决问题的复杂性;
2.求余数的思想