目录
力扣LCR 016无重复字符的最长子串
不知道哪个阴间大哥出的题目,开始我寻思哈希表模拟一下,我糙来,全是字符,/,‘\]
就是这种,超级抽象,那这样就不可以用数组模拟哈希表了,我直接使用简单的set,然后算一下长度,他有一个滑动窗口的思想,他的right式不用往回走,但是他的left要更新,因为我们需要移除left(假如left和right相同的情况 abkja 此时a相同,我们就需要移除a的值)
通过left确保a的位置 abkjk tyuiop
但是我这么做属于没错,但是性能有些问题
假如说,我使用left 我假如要是能获得当前重复的下标,我再去获取到他的下标,去更迭一下式最好的,但是这样,他的下标可能需要一个map? 反正可以优化,但是我懒的做了
public static int lengthOfLongestSubstring(String s) {
int left=0;
int right=0;
int Maxcount=0;
HashSet<Character>set=new HashSet<>();
while(right<s.length()) {
while (right < s.length()&&set.contains(s.charAt(right))==false ) {
set.add(s.charAt(right));
right++;
}
Maxcount = Math.max(set.size(), Maxcount);
set.remove(s.charAt(left));
left++;
}
return Maxcount;
}
力扣452.用最小数量的箭引爆气球
这里两个重点,会了就是轻松通过,1.两段区间中,要么我的起点比你终点小,并且,我的起点还大于你的终点,这就相当于 | | \ \ 这个区间的中间段,我可以改变我的区间长度,方便操作,假如不在这个区间段,就说明我一根箭穿不了你,所以需要再来一根
class Solution {
public static int findMinArrowShots(int[][] points) {
int n=points.length;
Arrays.sort(points,(a,b)-> {
if (a[0] - b[0] == 0) {
return a[1] - b[1];
} else {
return a[0] - b[0];
}
});
//[1,6][[2,8],[7,12][10,16]
int step=1;
for(int i=1;i<n;i++){
//其实要么我起点比你小,起点小于你的终点,并且我的起点还需要大于等于你的起点
// ((points[i][0]<0&&points[i-1][1]<0)||(points[i][0]>=0&&points[i-1][1]>=0))
if( points[i][0]>=points[i-1][0]
&&points[i][0]<=points[i-1][1]){
//此时,假如我们要是处理,必须要修改最后一个,因为我们是往前面取
points[i][1]=Math.min(points[i-1][1],points[i][1]);
}else{
step++;
}
}
return step;
}
}
LCR026.重排链表
老面孔了,但是你要是10分钟内写出来,还是稍微有点困难,所以在此回顾一下,他的逆序链表怎么逆序
记住你只需要三个节点 这个也不咋需要处理,因为(我自己想的不清楚对不对,她这个curpre这个位置只要保证随时都是逆序链表的未逆序状态第一个节点就好
比如 12345 6789 cur是变化的,但是cur的前一个节点,最终一定都是6,就是在整个过程中 假如7头插 6->8 8头插 6->9 )curpre cur 在循坏内部定义就行不用处理curnext
最后的合并连表,就是找到两个的头,然后分不同的区域,phead.next当前要搬过去的节点下一个就好不断更新
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode() {} * ListNode(int val) { this.val = val; } * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */ class Solution { public static void reorderList(ListNode head) { if(head.next==null)return; ListNode phead = new ListNode(); ListNode fast = head.next; ListNode slow = head; while (fast != null && fast.next != null) { slow = slow.next; fast = fast.next.next; } //1 2 3 4 // 1 2 3 4 5 6 7 8 9 ListNode cur = slow.next; slow.next = null; // 1 ,2 3,4 1,2,3,4 5 z 6,7,8,9 //连 p=6 phead.next = cur; ListNode curpre = cur; cur = cur.next; while (cur != null) { ListNode curnext = cur.next; cur.next=phead.next; phead.next = cur; curpre.next=curnext; cur = curnext; } //此时假如已经搞完了 1,2,3,4 5 z 9,8,7,6 ListNode cur1=head; ListNode cur2=phead.next; while(phead.next!=null&&cur1!=null){ cur2=phead.next; phead.next=cur2.next; cur2.next=cur1.next; cur1.next=cur2; cur1=cur2.next; } } }
力扣.1765地图中的最高点
首先思路就是假如是水,从水开始遍历,水周围的大陆添加进去,作为下一轮的遍历,使用ret来记录当前这层大陆的层高
static int[]dx={0,0,1,-1};
static int[]dy={1,-1,0,0};
static boolean [][]vis;
public static int[][] highestPeak(int[][] isWater) {
int n=isWater.length;
int m=isWater[0].length;
vis=new boolean[n][m];
int[][]grid=new int[n][m];
//可以考虑出两个
Queue<int[]>q=new LinkedList<>();
int max=0;
for(int i=0;i<n;i++) {
for (int j = 0; j < m; j++) {
//此时要考虑题意,我们考虑一下最大是什么情况,我们不应该关注走没走过啥的先
//考虑一下,水域附近是否有可能出现最大值,发现不可能,水域附近只可能是1
//换句话说这里是找1,而不是找0
//而且一个复杂的地方是,从1开始找,找到最后找不到了,再去找另一个1.
if (isWater[i][j] == 1) {
//存储多个0
q.add(new int[]{i, j});
vis[i][j]=true;
}
}
}
int ret=1;
//刚开始都是0,会进入3个0可能
while(!q.isEmpty()){
int sz=q.size();
while(sz!=0){
sz--;
int t[]=q.poll();
//开始假如等于1,把最开始的数字置为0,以陆地为基础
grid[t[0]][t[1]]=ret-1;
for(int i=0;i<4;i++){
int x=t[0]+dx[i];
int y=t[1]+dy[i];
//进入队列的要求是当前是陆地,开始假如等于1
if(x>=0&&x<m&&y>=0&&y<n&&
isWater[x][y]==0&&vis[x][y]==false){
//高度是最低的1
grid[x][y]=ret;
q.add(new int[]{x,y});
//给他标记上
vis[x][y]=true;
}
}
}
ret++;
}
return grid;
}