基础算法题目

leetcode是个很好的算法题网站

时间复杂度的基本类型:

O(1):常数复杂度 O(log n):对数复杂度 O(n):线性事件复杂度 O(n^2):平方

O(n^3):立方 O(2^n):指数 O(n!):阶乘

实例:移动零:(0,1,0,2,5)
把0移动到后面去 (此题是一维坐标的交替变换)

public void movezeroes(int [] nums){

int j=0
新加入的下标元素j 代表只要是非零元素那么就赋值到j上

for (int i=0;i<nums.length;++i){

    if

(nums[i]!=0){ 判断第一数字开始是不是不是0

     nums[j]=nums[i]      不是0就把i的值赋给j

     if (i!=j){              

             nums[i]=0        然后让i为0

}

j++
j继续往后走

}

}

}

盛水最多容器问题
(最优解) 也是两个坐标i j 时间复杂度:O(n^2)

public int maxarea(int [] a){

    int

max=0 初始化最大值

    for(int

i=0;j=a.length-1;i<j;){ 定义最右边j

             int

minHeight=a[i]<a[j]?a[i]++:a[j]-- 左右柱子哪个高 左边高i右移 右边高j左移

             int

area=(j-i+1) * minHeight 求以柱子较矮的为主的面积

             max=Math.max(max,area)      更新max

}

return max

}

(第二种解法)
时间复杂度:O(n) 左右夹逼

public int maxarea(int [] h){

    int

maxarea=0,int l=0,int r=h.length-1; 定义最左指针l 最右指针r 初始化面积

    while(l<r){

             maxarea=Math.max(maxarea,Math.min(h[l],h[r])*(r-l));   只要左指针在右指针左面  就计算每次移动的指针的面积

             }

    if(h[l]<h[r])

    h++;else

    l--;

retrun maxarea;

}

爬楼梯问题 递推法 F(0)=0
F(1)=1 F(2)=1 F(n)=F(n-1)+F(n-2)(也是斐波那契法 及即Fibonacci) 时间复杂度:O(1)

public int jumpFloor(int i){

    if(n==0)  return -1;

    if(n==1||n==2)  return n;

    else

    int

f1=1;

    int

f2=2;

    int

f3=3;

    for(i=0;i<n;i++){

             f3=f1+f2;

             f1=f2;

             f2=f3;

}

return f3;

}

三数之和问题:【-1,0,-4,-1,2,1】
让其三个数加一起等于0且无重复数 暴力求解发 hash表记录a b a+b=-c法 定义枚举指针 双指针夹逼法(即定义三个指针) O(n^2)

Arrays.sort方法是将数组内的元素进行升序排列 Arrays.asList方法是将数组转化为List集合的方法

public List<List>
threenum(int[] nums){

    Arrays.sort(nums);  将数组从小到大排列

    List<List<Integer>>

res=new LinkedList<>();
定义存放结果的数组

    for(int

i=0;i<nums.length-2;i++){ 因为l r最后在i的后两个上 所以不用重复循环

             if(nums[i]>0)

break; 当数组i上的数字大于0时 三数之和肯定大于0 直接跳出

             if(i==0||(i>0&&nums[i]!=nums[i-1])){   当i前后数值不一样时开始

                     int

l=i+1;int r=nums.length-1;int targer=0-nums[i];
i是枚举 l在i右侧 r在最左侧

                     while(l<r){

                              if(nums[l]+nums[r]==target){

                                      res.add(Arrays.asList(nums[i],nums[l],nums[r]));  符合的结果存入集合

                                      while(l<r&&nums[l]==nums[l+1])   l++;  排除l右侧的一样数

                                      while(l<r&&nums[r]==nums[r-1])   r--;  排除r左侧的一样数

                                      l++;

r–;

                                      else

if(nums[l]+nums[r]<nums[i]) l++; lr加一起的数小于i 那么就让l往右走 否则的话 就是r往左走

                                      else

r–;

}

}

}

}

}

return res;

}

链表反转(将一个顺序链表反转)(1->2->3->0变成0<-1<-2<-3)(三个辅助接点pqr 即每个节点的后续变成它的前驱) O(n)

public Node inverse(Node q){

    if(q==null)  return null;  

q是头节点(head) q空直接结束

    Node

p=null; 初始话p空

    Node

r=q.next; r是q的后一个节点

    while(r!=null){

             q.next=p;   pq换完之后   让pqr都往前进一个

             p=q;

             q=r;

             r=r.next;

}

q.next=p;
最后一次r到空指针上 pq进行最后转换

return q;

}

static class Node{

    Node

next;

    int

data;

    Node(int

data){

             this.data=data;  this.next=next;

}

}

判断链表是否有环(采用快慢指针法)O(n)

public Boolean hasCycle(Node head){

    if(head==null||head.next==null){

             return

false;

}

    Node

slow=head; Node fast=head.next;

    while(slow!=fast){

             if(fast==null||fast.next==null){

                     return

flase;

}

             slow=slow.next;

fast=fast.next.next;

}

    return

true;

}

static class Node{

    Node

next;

    int

data;

    Node(int

data){

             this.data=data;  this.next=next;

}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值