力扣刷题(基础相关知识的学习)

本文探讨了时间复杂度的概念,涉及不同复杂度级的算法示例,如O(1), O(N), O(logN), O(M+N), O(NlogN),以及空间复杂度的定义,重点关注数组和链表的存储空间。通过实例分析,讲解了如何评估算法执行时间和空间需求。此外,还介绍了Java中数组操作、排序和链表的基本操作及其复杂度。
摘要由CSDN通过智能技术生成

时间复杂度

什么是时间复杂度

算法的执行效率
算法的执行时间与算法的输入值之间的关系
一般看是否有for循环或者while循环

常见的时间复杂度案例分析

O(1):和定义的数的输入无关

int n=4;
int j=n*2;
System.out.print(j);

O(N)

for(int i=0;i<num;i++)
{
	total=total+i;
}

O(log N)

i=1;
while(i<num)
	i=i*2;
return i;

O(M+N):一般是两个并列的循环

for(int i=0;i<num1;i++)
for(int j=0;j<num2;j++)

O(NlogN)互相套用的循环

total=0;
j=0;
for(int i=0;i<num1;i++
{
	while(j<num2)
	{
		total=total+i+j;
		j=j*2;
	}
}
return total;

空间复杂度

什么是空间复杂度

算法存储空间与输入值之间的关系
观察变量,观察是否有递归

数组Array使用方法

数组:在连续的内存空间中,存储一组相同类型的元素(必须是连续空间)

数组与索引

数组的索引都是从0开始的,索引代表在内存空间中相对的位置

数组访问(access)和数组搜索(search)

访问:通过索引进行访问
搜索:遍历数组查看相同值

  1. 访问Access O(1)
  2. 搜索Search O(N)
  3. 插入Insert O(N)
  4. 删除Delete O(N)

Java数组常用操作

定义数组的方法

//知道数组内容的情况下
int[] a={1,2,3};
int[] b=new int[]{1,2,3};
//知道数组长度的时候
int[] c=new int[3];

//当不知道数组长度,不知道数组的内容的时候可以使用以下方法
ArrayList<Integer> arr=new ArrayList<>();
//不过这种方法需要在开头处加上import java.util.ArrayList;

数组添加元素

在前三种定义的情况下,在添加新的元素的时候可以定义一个长度增加的数组,并且把原来数组的值赋值给新的数组,然后增加的位置赋值需要添加的新的元素。最后可以使用新数组,也可以旧数组等于新数组(赋值)使用新的数组。

  • 添加元素:可以使用 arr.add()函数。
    比如 arr.add(3,66)表示索引为3的地方插入数字66

  • 访问元素:可以使用arr.get(1)表示访问索引为1的元素

  • 更新元素:arr.set(i,j)表示索引 i 的元素更换为 j

  • 删除元素:arr.remove(0)

  • 遍历数组:arr.size()与a.length用法相同

		Scanner in=new Scanner(System.in);
		ArrayList<Integer> arr=new ArrayList<>();
		for(int i=0;i<=2;i++)
		{
			int a=in.nextInt();
			arr.add(a);//输入1,2,3
		}
		System.out.println("arr:"+arr.toString());
		arr.add(3,5);//索引为3的位置增加数字5
		System.out.println("arr数组添加之后:"+arr.toString());
		int arr1=arr.get(3);//查询索引为3的元素
		System.out.println("查询数组:"+arr1);
		arr.set(0, 11);//索引为0的位置更换元素成11
		System.out.println("arr数组更换元素之后:"+arr.toString());
		arr.remove(0);//填入的是索引
		System.out.println("arr删除:"+arr.toString());

数组排序(java自带函数运用)

时间复杂度:O(NlogN)

//java自带的从小到大的排序方法
		int[] c= {2,3,1};
		ArrayList<Integer> arr=new ArrayList<>();
		arr.add(2);
		arr.add(3);
		arr.add(1);
		System.out.println("c:"+Arrays.toString(c));
		System.out.println("arr:"+arr.toString());
		
		Arrays.sort(c);//对于第一第二中定义数组的方法
		System.out.println("c:"+Arrays.toString(c));
		
		Collections.sort(arr);//针对最后一种
		System.out.println("arr:"+arr.toString());
		'''输出结果:
		c:[2, 3, 1]
		arr:[2, 3, 1]
		c:[1, 2, 3]
		arr:[1, 2, 3]'''

从大到小排序:
如果是定义a,b,c这一类的数组,一种方法可以先从小到大排列,之后倒序输出。另一种方法是将int转换为array类型。
Array数组函数方式:

		ArrayList<Integer> arr2=new ArrayList<>();
		arr2.add(2);
		arr2.add(3);
		arr2.add(1);
		Collections.sort(arr2,Collections.reverseOrder());
		System.out.println("arr2:"+arr2.toString());
		'''
		arr2:[3, 2, 1]
		'''

485.最大连续1的个数

  • 题目:
    输入:nums = [1,1,0,1,1,1]
    输出:3
    解释:开头的两位和最后的三位都是连续 1 ,所以最大连续 1 的个数是 3

  • 思路:
    定义count计算连续1的个数,result记录最终最大的数。注意在遍历数组之后要考虑如果最后一个数字是1的情况下,result还没有成为count所表达的数

class Solution {
    public int findMaxConsecutiveOnes(int[] nums) {
        int count=0;
        int result=0;
        ArrayList<Integer> arr=new ArrayList<>();//不用知道数组的长度和内容
        for(int i=0;i<nums.length;i++)
        {
            if(nums[i]==1)
                count++;
            else
            {
                result=Math.max(result,count);
                count=0;
            }
        }
        return result=Math.max(result,count);//注意最后一个数字是1的情况
    }
}

283.移动零

  • 题目:
    输入: nums = [0,1,0,3,12]
    输出: [1,3,12,0,0]
    不可以进行数组的复制

- 思路:
定义一个从0的索引,并且遍历一边数组找到所有不为0的数。最后把剩下的位置赋值0。这道题的做题思路比较重要。

class Solution {
    public void moveZeroes(int[] nums) {
        int index=0;
        for(int i=0;i<nums.length;i++)
        {
            if(nums[i]!=0)
            {
                nums[index]=nums[i];
                index++;
            }
        }
        for(int j=index;j<nums.length;j++)
        {
            nums[j]=0;
        }
    }
}

27.移除元素

数组元素的置换问题

双指针算法

i 指针找到指定的值停下来,j 指针找不到指定值就停下来
然后 i 和 j 所指位置的两个数字进行交换,然后继续进行
终止条件:i>=j(i=j / i>j)
当i==j的时候
查看索引位置的元素与给定元素是否相同,如果相同则输出i;
如果不相同则输出i+1;

题目描述:
输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2]
这道题要注意如果所给定的数组长度为0的时候,不用进行接下来的判断操作。并且在while循环内的while循环的写法

class Solution {
    public int removeElement(int[] nums, int val) {
      if(nums==null||nums.length==0)
        return 0;
      int l,r;
      l=0;
      r=nums.length-1;
      while(l<r)
      {
          while(l<r&&nums[l]!=val)
          {
              l++;
          }
          while(l<r&&nums[r]==val)
          {
              r--;
          }
          int temp;
          temp=nums[l];
          nums[l]=nums[r];
          nums[r]=temp;
      }
      if(nums[l]==val)
      {
          return l;
      }
      else
      {
          return l+1;
      }
    }
}

链表常用操作

数组:连续的内存
链表:元素+指针
访问access O(N)
搜索search O(N)
插入 insert O(1)
删除 delete O(1)

java链表常用操作

创建链表

LinkedList<Integer> list = new LinkedList<>();

添加元素

		list.add(1);//从尾端进行插入
		list.add(2);
		list.add(3);
		System.out.print(list.toString());
		System.out.printf("\n");
		// 1 2 3
		
		list.add(2,99);//从已知位置插入数字
		System.out.print(list.toString());
		System.out.printf("\n");

访问元素

	int a=list.get(2);
	System.out.println(a);

搜索元素

		int index=list.indexOf(99);
		System.out.println(index);

更新元素

		list.set(2,88);
		System.out.println(list.toString());

删除元素

		list.remove(2);
		System.out.println(list.toString());

长度

		int length=list.size();
		System.out.println(length);

203移除链表

  • 给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。
  • 1-2-6-3-4-5-6 val=6
    1-2-3-4-5
  • 解题思路:首先定义一个header在整个链表之前,从第一个数字开始遍历,分情况讨论:如果该数字==val,那么处理 prev.next=prev.next.next;如果该数字不等于val,那么prev=prev.next。
class Solution {
    public ListNode removeElements(ListNode head, int val) {
        ListNode header=new ListNode(-1);
        header.next=head;
        ListNode prev=header;
        while(prev.next!=null){
            if(prev.next.val==val)
            {
                prev.next=prev.next.next;
            }
            else{
                prev=prev.next;
            }
        }
        return header.next;
    }
}

206反转链表(???)

  • 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
  • 1 2 3 4 5
  • 5 4 3 2 1
class Solution {
    public ListNode reverseList(ListNode head) {
         ListNode prev = null; //前指针节点
        ListNode curr = head; //当前指针节点
        //每次循环,都将当前节点指向它前面的节点,然后当前节点和前节点后移
        while (curr != null) {
            ListNode nextTemp = curr.next; //临时节点,暂存当前节点的下一节点,用于后移
            curr.next = prev; //将当前节点指向它前面的节点
            prev = curr; //前指针后移
            curr = nextTemp; //当前指针后移
        }
        return prev;
    }
}

栈的学习

先入后出,后入先出

创建站stack

Stack<Integer> stack = new Stack<>();

添加元素

stack.push(1);
stack.push(2);
stack.push(3);
System.out.println(stack.toString());

获取栈顶元素

stack.peek();

删除栈顶元素

int temp=stack.pop();

获取栈的大小

stack.size();

栈是否为空

stack.isEmpty();

栈的遍历

while(!stack.isEmply())
{
	int num=stack.pop();
	System.out.println(num);
}

哈希表

创建哈希表

添加元素

利用数组创建一个哈希表,将数组的索引当作key,数组的值当作value

String[] hashTable = new String[4]
//添加元素方法
hashTable[1]="001";
hashTable[2]="002";
hashTable[3]="003";

利用hashmap创建哈希表

HashMap<Interger,String> map=new HashMap<>();
//第一个是key的类型,第二个是value类型
//添加元素方法
map.put(1,"001");
map.put(2,"002");
map.put(3,"003");

更新元素

hashTable[1]="005";
map.put(1,"005");//直接覆盖原值

删除元素

对于利用数组进行创建的情况下,可以将要删除的数定义成一个不常用到的数字,比如空字符串。

hashTable[1]="";
map.remove(1);

获取元素

String temp=hashTable[3];
map.get(3);

检查key是否存在

map.containsKey(3);

长度

map.size();
map.isEmpty();
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值