leetcode刷题(四)java

本文介绍了三种数组操作的方法:分割数组使其左侧元素都不大于右侧元素,并返回左侧长度;寻找数组的中心下标,即左侧元素之和等于右侧元素之和的位置;在二维网格中计算从起点到终点的不同路径数量,要求经过所有无障碍方格。

10.分割数组

给定一个数组 A,将其划分为两个连续子数组 leftright, 使得:

  • left 中的每个元素都小于或等于 right 中的每个元素。
  • leftright 都是非空的。
  • left 的长度要尽可能小。

在完成这样的分组后返回 left长度。可以保证存在这样的划分方法。

class Solution {
    public int partitionDisjoint(int[] A) {
        int n=A.length;
        int[] ans=new int[n];
        ans[0]=1;
        int m=A[0],t=A[0];
        for(int i=1;i<n;i++)
        {
            if(A[i]<m)
            {
                ans[i]=i+1;
                m=t;
            }
            else
            {
                ans[i]=ans[i-1];
                if(A[i]>=t)
                {
                    t=A[i];
                }
            }
        }
        return ans[n-1];

    }
}

11.寻找中心下标

给你一个整数数组 nums,请编写一个能够返回数组 “中心下标” 的方法。

数组 中心下标 是数组的一个下标,其左侧所有元素相加的和等于右侧所有元素相加的和。

如果数组不存在中心下标,返回 -1 。如果数组有多个中心下标,应该返回最靠近左边的那一个。

**注意:**中心下标可能出现在数组的两端。

class Solution {
    public int pivotIndex(int[] nums) {
        int sum1=0,sum2=0;
        int n=nums.length;
        if(n==0)
        {
            return -1;
        }
        if(n==1)
        {
            return 0;
        }
        for(int i=1;i<n;i++)
        {
            sum2=sum2+nums[i];
        }
        if(sum1==sum2)
        {
            return 0;
        }
        for(int i=1;i<n;i++)
        {
            sum1=sum1+nums[i-1];
            sum2=sum2-nums[i];
            if(sum1==sum2)
            {
                return i;
            }
        }
        return -1;
        
    }
}

12.不同路径III

在二维网格 grid 上,有 4 种类型的方格:

  • 1 表示起始方格。且只有一个起始方格。
  • 2 表示结束方格,且只有一个结束方格。
  • 0 表示我们可以走过的空方格。
  • -1 表示我们无法跨越的障碍。

返回在四个方向(上、下、左、右)上行走时,从起始方格到结束方格的不同路径的数目**。**

每一个无障碍方格都要通过一次,但是一条路径中不能重复通过同一个方格

class Solution {
    
    public static int dps(int[][] grid,int i,int j,int m,int n,int s,int l)//i,j是当前位置
    {
        int ans=0;
        if(i<0||j<0||i>=m||j>=n||grid[i][j]==-1||grid[i][j]==1)
        {
            return 0;
        }
        else if(grid[i][j]==2)
        {
            if(s==l)
            {
                return 1;
            }
            else{
                return 0;
            }
        }
        else
        {
            if(grid[i][j]==0)
            {
                s=s+1;
                grid[i][j]=-1;
                ans=ans+dps(grid,i+1,j,m,n,s,l);
                ans=ans+dps(grid,i,j+1,m,n,s,l);
                ans=ans+dps(grid,i-1,j,m,n,s,l);
                ans=ans+dps(grid,i,j-1,m,n,s,l);
                grid[i][j]=0;
            }
        }
        return ans;
    }

    public int uniquePathsIII(int[][] grid) {
        int ans=0;
        int m=grid.length,n=grid[0].length;
        int l=0;
        int start_i=0,start_j=0;
        for(int i=0;i<m;i++)
        {
            for(int j=0;j<n;j++)
            {
                if(grid[i][j]==1)
                {
                    start_i=i;
                    start_j=j;
                }
                if(grid[i][j]==0)
                {
                    l=l+1;
                }
            }
        }
        int i=start_i,j=start_j;
        int s=0;
        ans=ans+dps(grid,i+1,j,m,n,s,l);
        s=0;
        i=start_i;
        j=start_j;
        ans=ans+dps(grid,i,j+1,m,n,s,l);
        s=0;
        i=start_i;
        j=start_j;
        ans=ans+dps(grid,i-1,j,m,n,s,l);
        s=0;
        i=start_i;
        j=start_j;
        ans=ans+dps(grid,i,j-1,m,n,s,l);
        return ans;
    }
}
### LeetCode Java 教程技巧 #### 使用合适的数据结构 对于特定类型的目,选择适当的数据结构可以简化问并提高效率。例如,在处理队列操作时,`Deque<Integer> deque = new LinkedList<>();` 是一种有效的方式来初始化双端队列[^1]。 #### 动态规划的应用实例 以格雷编码为例,该类问可以通过动态规划的方法解决。具体来说,基于前一阶段的结果构建下一阶段的解决方案。比如从第 `n` 层的格雷码序列出发,通过在其反转后的每一个元素前面加上 '1' 来形成新的 `(n+1)` 层格雷码列表[^3]。 #### 子问分解策略 当面对复杂度较高的算法设计时,将大问拆分成若干个小而简单的子问是常见的做法之一。如果能够确保这些子问之间相互独立,则整个过程中的总工作量大致等于各部分之。这表明随着输入大小的增长,所需处理的任务数目呈线性增长趋势,即时间复杂度为 O(n)[^4]。 #### 实战练习建议 为了更好地掌握编程技能以及应对实际面试场景下的挑战,定期参与像力扣这样的在线平台上的竞赛活动是非常有益处的。这里不仅提供了丰富的习资源供学习者反复操练,还允许用户提交自己的解答并与他人分享交流心得体验[^2]。 ```java // 示例代码:创建一个双向链表作为双端队列 Deque<Integer> deque = new LinkedList<>(); deque.addFirst(1); // 向头部添加元素 deque.addLast(2); // 向尾部添加元素 System.out.println(deque.pollFirst()); // 移除并返回最左边的元素 System.out.println(deque.pollLast()); // 移除并返回最右边的元素 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值