知识点
- 数组是存放在连续内存空间上的相同类型数据的集合。
- 数组下标都是从0开始的。
- 数组内存空间的地址是连续的
- 数组的元素是不能删的,只能覆盖。
- 二维数组在内存的空间地址不一定连续
- 不同编程语言的内存管理是不一样的,以C++为例,在C++中二维数组是连续分布的。
- Java中二维数组不是连续分布的
二分查找(lc704)
方法1 普通遍历
代码1.1(错误)
class Solution {
public int search(int[] nums, int target) {
for(int i=0; i<nums.length; i++){
if target == nums[i]
return i;
else
return -1;
}
}
}
执行结果:出错了,if 后面忘记写括号了,暑假学深度学习、python,现在写Java,忘记需要写括号了 [笑哭]
代码1.2(错误)
class Solution {
public int search(int[] nums, int target) {
for(int i=0; i<nums.length; i++){
if (target == nums[i])
return i;
else
return -1;
}
}
}
改动:if语句加了括号
执行结果:编译错误,Line 10: error: missing return statement
代码1.3(错误)
class Solution {
public int search(int[] nums, int target) {
for(int i=0; i<nums.length; i++){
if (target == nums[i])
return i;
else
return -1;
}
}
return 0;
}
改动:加了个return 0;
执行结果:Line 11: error: illegal start of type
return 0;
代码1.4(错误)
class Solution {
public int search(int[] nums, int target) {
for(int i=0; i<nums.length; i++){
if (target == nums[i])
return i;
else
return -1;
}
return 0;
}
}
改动:return 0;的位置变了一下
疑惑:为啥这个代码错了???
错因:我写的这个只是比较的第一个元素,第一个元素不匹配,后面的元素就没匹配,直接return -1了
代码1.5(正确)
在网上借鉴别人代码后所写
class Solution {
public int search(int[] nums, int target) {
int count = -1;
if(nums.length == 0)
return count;
for(int i=0; i<nums.length; i++){
if (target == nums[i])
return i;
}
return count;
}
}
改动:加了个数组长度为0时候的判断
代码1.6(正确,但效率不高)
class Solution {
public int search(int[] nums, int target) {
if(nums.length == 0)
return -1;
for(int i=0; i<nums.length; i++){
if (target == nums[i])
return i;
}
return -1;
}
}
方法2 二分查找
2.1 左闭右闭写法(最普通的写法)
class Solution {
public int search(int[] nums, int target) {
int left = 0, right = nums.length-1;
while(left <= right){
int mid = left + (right-left)/2;
if(nums[mid] == target){
return mid;
}
else if(nums[mid] < target){
left = mid +1;
}
else{
right = mid -1;
}
}
return -1;
}
}
2.2 左闭右开写法
class Solution {
public int search(int[] nums, int target) {
int left = 0, right = nums.length; //right不是等于length-1
while(left < right){ //此处不是小于等于
int mid = left + (right - left)/2; //mid前面的元素类型别忘了
if(nums[mid] < target){
left = mid + 1;
}
else if(nums[mid] > target){
right = mid;
}
else if(nums[mid] == target){ //一定是==,而不是=
return mid;
}
}
return -1;
}
}
移除元素(lc27)
方法1 暴力解法
错误写法
class Solution {
public int removeElement(int[] nums, int val) {
int count = nums.length;
for(int i=0; i<nums.length; i++){
if(nums[i] == val){
count --;
for(int j=i; j<nums.length-1; j++){
nums[j] = nums[j+1];
}
}
}
return nums[count];
}
}
错因:当在位置i找到一个与val相同的元素,后面的元素依次往前移动覆盖此元素,⚠️下次还是从i位置处开始判断nums[i]与val是否相同,而不是nums[i+1]与val是否相同
正解写法1
class Solution {
public int removeElement(int[] nums, int val) {
int count = nums.length;
for(int i=0; i<count; ){
if(nums[i] == val){
count --;
for(int j=i; j<nums.length-1; j++){
nums[j] = nums[j+1];
}
}
else
i++;
}
return count;
}
}
正解写法2
class Solution {
public int removeElement(int[] nums, int val) {
int count = nums.length;
for(int i=0; i<count;i++ ){ //i必须<count,而不是nums.length,
//例:如果最后一个元素是val的话,
if(nums[i] == val){
count --;
for(int j=i; j<nums.length-1; j++){
nums[j] = nums[j+1];
}
i--;
}
//i--;在这个位置不对
}
return count;
}
}
方法2 双指针法(快慢指针)
- 快指针:寻找新数组的元素 ,新数组就是不含有目标元素的数组
- 慢指针:指向更新 新数组下标的位置
- 快慢指针这种做法没有改变元素的相对位置
错误写法
class Solution {
public int removeElement(int[] nums, int val) {
int slow = 0 , fast = 0;
while(fast < nums.length){
if(nums[fast] == val){
fast++;
nums[slow] = nums[fast];
slow++;
}
}
return slow + 1;
}
}
正解写法1
class Solution {
public int removeElement(int[] nums, int val) {
int slow = 0 , fast = 0;
while(fast < nums.length){
if(nums[fast] != val){
nums[slow] = nums[fast];
slow++;
}
fast++;
}
return slow;
}
}
写法2
class Solution {
public int removeElement(int[] nums, int val) {
int fast=0, slow=0;
for(int i=0; i<nums.length; i++){
if(val != nums[fast]){
nums[slow] = nums[fast];
fast++;
slow++;
}
else
fast++;
}
return slow;//因为在第8行有slow++,所以最后slow的位置一定是往后多1的
}
}