当前位置:网站首页>587. 安装栅栏 / 剑指 Offer II 014. 字符串中的变位词
587. 安装栅栏 / 剑指 Offer II 014. 字符串中的变位词
2022-04-23 17:41:00 【彼淇梁】
587. 安装栅栏【困难题】【每日一题】
思路:
直接看题解,理解了半天~ 写在注释里了,但愿我下次看见还记得今天怎么理解的…
代码:
class Solution {
public int[][] outerTrees(int[][] trees) {
int n = trees.length;
if (n < 4){
//树小于4时,所有的树都在边界,必须被围住,于是直接返回trees
return trees;
}
//对trees先按 x 坐标排序,x坐标相等时按 y 坐标排序 (均为升序)
Arrays.sort(trees,(a,b)->(a[0] == b[0] ? a[1]-b[1] : a[0]-b[0]));
int tp = 0;//tp表示栈顶元素下标
int[] stk = new int[n+10];//通过stk数组实现栈功能,stk中存入的是tree在trees中的下标
boolean[] vis = new boolean[n+10];//vis数组用于标记当前这个位置的树是否需要处在边界,即是否需要使用
stk[++tp] = 0;//向栈中压入第一个tree,tp现在为1
//trees数组排好序之后,第一个tree必然要处在边界,因此从第2个tree开始遍历
//画第一部分凸包,即下半部分(以trees左右端点连线为界)
for (int i = 1; i < n; i++) {
//按顺序遍历所有的tree
int[] c = trees[i];//用c表示当前树坐标
while (tp >= 2){
//当栈里有超过两个元素时,才需要判断当前树是否在边界
//取出栈顶树坐标 b,以及栈顶的上一个树坐标 a
int[] a = trees[stk[tp-1]], b = trees[stk[tp]];
//判断向量ac是否在ab左边
if (getArea(a,b,c) < 0){
//ac在ab右边,那么说明c更符合边界条件,需要废弃b节点
//于是将此时栈顶节点 b 废弃,即在vis中对应 b 的下标位置置为false,同时栈顶下标自减1,表示移除栈顶下标
vis[stk[tp--]] = false;
}else {
//ac在ab左边,那么退出while循环处理将当前树压入栈即可
break;
}
}
stk[++tp] = i;//向栈中压入当前树的下标
vis[i] = true;//标记当前树已被选为边界
}
int size = tp;//记录第一部分凸包已经有几个树
//画第二部分凸包,即凸包的上半部分
for (int i = n-1; i >= 0 ; i--) {
if (vis[i]){
//如果当前树已被使用,则直接去判断下一棵树
continue;
}
int[] c = trees[i];//取出当前遍历到的树
while (tp > size){
//当栈中元素个数大于第一部分凸包个数时
//取出栈顶元素 b 和 栈顶元素的上一个元素 a
int[] a = trees[stk[tp-1]],b = trees[stk[tp]];
//判断向量ac是否在向量ab左边
if (getArea(a,b,c) < 0){
//如果ac在ab右边,那么将栈顶上一个元素 废弃
vis[stk[tp--]] = false;
}else {
//如果ac在ab左边,那么退出while循环,将当前树压入栈
break;
}
}
stk[++tp] = i;//将当前树的下标i压入栈
vis[i] = true;//将当前树标记为已使用状态
}
int[][] ans = new int[tp-1][2];
for (int i = 1; i < tp; i++) {
ans[i-1] = trees[stk[i]];//将栈中元素对应的trees中树存入ans数字返回
}
return ans;
}
public int[] subtraction(int[] a,int[] b){
//二维向量相减
return new int[]{
a[0]-b[0],a[1]-b[1]};
}
public double cross(int[] a,int[] b){
//二维向量叉乘
return a[0]*b[1]-a[1]*b[0];//结果大于0表示向量b在向量a左侧,结果小于0表示向量b在向量a右侧
}
public double getArea(int[] a,int[] b,int[] c){
//计算向量ab转为向量ac的过程中
//结果大于0表示向量ac在向量ab左侧,结果小于0表示向量ac在向量ab右侧
return cross(subtraction(b,a),subtraction(c,a));
}
}
剑指 Offer II 014. 字符串中的变位词【中等题】
思路:
统计
s1中各个字符出现的次数,用一个长度与s1相等的滑动窗口框住s2,统计窗口内的各个字符出现次数,如果s1中字符出现次数与s2滑动窗口内字符出现次数相同,那么表示s2包含s1的某个变位词。
窗口滑动时,将窗口左侧字符次数减1,将窗口右侧字符次数加1即可实现窗口内字符次数统计的更新,而不用重新统计整个窗口的字符出现次数。
代码;
class Solution {
public boolean checkInclusion(String s1, String s2) {
int n1 = s1.length(),n2 = s2.length();
if (n1 > n2){
return false;
}
int[] cnt1 = new int[26],cnt2 = new int[26];
char[] chars1 = s1.toCharArray(),chars2 = s2.toCharArray();
for (char c : chars1) {
//统计字符串s1中每个字符的个数
cnt1[c-'a']++;
}
for (int i = 0; i < n1; i++) {
//统计字符串s2前n1个字符中每个字符的个数
cnt2[chars2[i]-'a']++;
}
if (Arrays.equals(cnt1,cnt2)){
return true;
}
for (int i = 1; i < n2-n1+1; i++) {
cnt2[chars2[i-1]-'a']--;//将当前窗口左端字符个数减1
cnt2[chars2[i+n1-1]-'a']++;//将当前窗口右端字符个数加1
if (Arrays.equals(cnt1,cnt2)){
return true;
}
}
return false;
}
}
版权声明
本文为[彼淇梁]所创,转载请带上原文链接,感谢
https://blog.csdn.net/weixin_42593011/article/details/124365221
边栏推荐
猜你喜欢

flink 学习(十二)Allowed Lateness和 Side Output

2. Electron's HelloWorld

Qt error: /usr/bin/ld: cannot find -lGL: No such file or directory

440. The k-th small number of dictionary order (difficult) - dictionary tree - number node - byte skipping high-frequency question

Kubernetes 服务发现 监控Endpoints

EasymodbusTCP之clientexample解析

土地覆盖/利用数据产品下载

PC uses wireless network card to connect to mobile phone hotspot. Why can't you surf the Internet

Qt error: /usr/bin/ld: cannot find -lGL: No such file or directory

2021长城杯WP
随机推荐
tidb-server 的配置文件在哪里?
剑指 Offer 22. 链表中倒数第k个节点-快慢指针
读《Software Engineering at Google》(15)
Manually implement simple promise and its basic functions
超分之TDAN
[binary number] maximum depth of binary tree + maximum depth of n-ary tree
双闭环直流调速系统matlab/simulink仿真
Arithmetic expression
Change Oracle to MySQL
198. 打家劫舍-动态规划
Collection of common SQL statements
JS failed to change all variables and changed to the return method. Finally, the problem was solved
XTask与Kotlin Coroutine的使用对比
Understanding of RPC core concepts
Why do some people say SCM is simple and I have to learn it so hard?
ES6 new method
Future usage details
MySQL进阶学习之SQL优化【插入,主键,排序,分组,分页,计数】
Using quartz under. Net core -- job attributes and exceptions of [4] jobs and triggers
Manually implement call, apply and bind functions