当前位置: 首页 > wzjs >正文

济源做网站的好公司施工企业qc小组

济源做网站的好公司,施工企业qc小组,jpress和wordpress哪个好,企业seo优化服务目录 一、3502. 到达每个位置的最小费用二、3503. 子字符串连接后的最长回文串 I三、3504. 子字符串连接后的最长回文串 II四、3505. 使 K 个子数组内元素相等的最少操作数 一、3502. 到达每个位置的最小费用 题目链接 本题是一道脑筋急转弯,实际就是计算前缀最小…

目录

  • 一、3502. 到达每个位置的最小费用
  • 二、3503. 子字符串连接后的最长回文串 I
  • 三、3504. 子字符串连接后的最长回文串 II
  • 四、3505. 使 K 个子数组内元素相等的最少操作数

一、3502. 到达每个位置的最小费用

题目链接
在这里插入图片描述
本题是一道脑筋急转弯,实际就是计算前缀最小值,画个图理解一下:
在这里插入图片描述
代码如下:

class Solution {public int[] minCosts(int[] cost) {int n = cost.length;int[] ans = new int[n];ans[0] = cost[0];for(int i = 1; i < n; i++){ans[i] = Math.min(ans[i-1], cost[i]);}return ans;}
}

二、3503. 子字符串连接后的最长回文串 I

题目链接
在这里插入图片描述
本题数据范围较小,直接暴力,代码如下:

class Solution {public int longestPalindrome(String s, String t) {int n = s.length();int m = t.length();int ans = 1;for(int i = 0; i < n; i++){for(int j = i; j < n; j++){if(check(s.substring(i,j+1))){ans = Math.max(ans, j-i+1);}for(int x = 0; x < m; x++){for(int y = x; y < m; y++){if(check(s.substring(i,j+1) + t.substring(x,y+1))){ans = Math.max(ans, j-i+1+y-x+1);}if(check(t.substring(x,y+1))){ans = Math.max(ans, y-x+1);}}}}}return ans;}boolean check(String s){int l = 0, r = s.length() - 1;while(l < r){if(s.charAt(l) != s.charAt(r))return false;l++;r--;}return true;}
}

三、3504. 子字符串连接后的最长回文串 II

题目链接
在这里插入图片描述
本题要构造一个最长的回文串,可以将它分成三个部分 —— ABA,它有两种情况:

  • 情况一:s = "???AB??", t = "???A??",A1 与 A2 互相回文,B 自身是一个回文串
  • 情况二:s = "???A???", t = "??BA??",A1 与 A2 互相回文,B 自身是一个回文串
  • 注:A,B 长度都可以为 0

举一个例子 s = "???abcac??", t = "???ba??",这里 A1 = “ab”,B = “cac”,A2 = “ba”,可以将它拆分成两个部分:

  • A1 与 A2,这里换一个视角,将 A2 翻转过来,A1 就等于 A2,所以可以将 字符串t 反转一下,这部分实际上就变成了一个求 s 与 resT 的最长公共子串问题,可以使用 dp 来解决。
    • 定义 f [ i ] [ j ] f[i][j] f[i][j]:以 i i i 结尾的字符串 s s s 与 以 j j j 结尾的字符串 r e s T resT resT 的最长公共子串
    • s [ i ] s[i] s[i] != r e s T [ j ] resT[j] resT[j] f [ i ] [ j ] = 0 f[i][j] = 0 f[i][j]=0
    • s [ i ] s[i] s[i] == r e s T [ j ] resT[j] resT[j] f [ i ] [ j ] = f [ i − 1 ] [ j − 1 ] + 1 f[i][j] = f[i-1][j-1]+1 f[i][j]=f[i1][j1]+1
  • B 这部分可以使用中心扩展法来枚举,由于回文串的长度可奇可偶,对于一个长度为 n n n 的字符串,需要枚举的中心点就有 n + ( n − 1 ) n + (n - 1) n+(n1) 个(奇数中心有 n n n 个,偶数中心有 n − 1 n-1 n1 个),可以从 0 枚举到 2 ∗ n − 2 2 * n - 2 2n2,此时可以直接得到 l = i / 2 , r = ( i + 1 ) / 2 l=i/2, r=(i+1)/2 l=i/2,r=(i+1)/2,然后向两边扩展就行。
  • 此时的答案等于: r − l + 1 + 2 ∗ m a x ( f [ l − 1 ] ) r-l+1+2*max(f[l-1]) rl+1+2max(f[l1])

代码如下:

class Solution {int dfs(String S, String T){char[] s = S.toCharArray();char[] t = T.toCharArray();int n = s.length, m = t.length;int[][] f = new int[n+1][m+1];int[] mx = new int[n+1]; // 统计以 i-1 结尾的字符串S 与 字符串T 的最长公共子串长度int ans = 0;for(int i = 0; i < n; i++){for(int j = 0; j < m; j++){if(s[i] == t[j]){f[i+1][j+1] = f[i][j] + 1;mx[i+1] = Math.max(f[i+1][j+1], mx[i+1]);}}ans = Math.max(ans, 2 * mx[i+1]); // B 为 0 的情况}for(int i = 0; i < 2 * n - 1; i++){ // 中心扩展int l = i / 2;int r = (i + 1) / 2;while(l >= 0 && r < n && s[l] == s[r]){l--;r++;}if(l+1 <= r-1) // 判断 s[l+1, r-1] 不为空 ans = Math.max(ans, r - l - 1 + 2 * mx[l+1]);}return ans;}public int longestPalindrome(String s, String t) {String resT = new StringBuilder(t).reverse().toString();// 分别计算 AB与A,A与BA 两种情况return Math.max(dfs(s, resT), dfs(resT, s)); }
}

四、3505. 使 K 个子数组内元素相等的最少操作数

题目链接
在这里插入图片描述
本题是一道综合题:

  • 长度为 x x x 的子数组,说明要使用 滑动窗口
  • 求子数组中所有元素相等的最小操作次数,肯定是变成中位数操作次数最小,求中位数
  • 求包含 k k k 个长度 恰好 为 x 的不重叠子数组(每个子数组中的所有元素都相等)所需要的最少操作数,这是 dp

先来解决如何计算滑窗中位数,使用对顶堆解决,准备两个堆,一个大根堆 left,一个小根堆right

  • 由特殊到一般,如果给定一个无序数组,如何求它的中位数(不排序做法)
    • 中位数只会出现在有序数组的中间位置,所以可以使用 left 来统计数组的前半段,right 来统计数组的后半段,保证 left.size() >= right.size(),此时中位数一定就是 left的堆顶元素(1/2个)。明确了大概的方向,接下来就是如何动态维护元素入堆
    • 对于元素 x,如何判断它是进入 left 还是 right,分情况讨论:
      • 如果 left.size() <= right.size(),那么一定要把x放入left,但是这里会出现一个问题,x 可能比rgiht.peek()还要大,如果直接把 x 放入left,那么有序性就被打破,所以最好的做法是先将 x 放入right,然后把 right.poll() 放入 left 中
      • 如果 left.size() > right.size(),那么一定要把x放入right,但是这里也会出现一个问题,x 可能比left.peek()还要小,如果直接把 x 放入right,那么有序性就被打破,所以最好的做法是先将x放入left,然后把 left.poll() 放入 right 中
  • 上述做法已经把入堆的操作讲完了,接下来就是在滑窗过程中如何出元素,假设该元素为 out
    • 先判断 out 在那个堆当中
    • 如果 out <= left.peek(),说明它在left,需要将它从left移除。但是仅仅这样还不行,它还会出现一个问题如果移除之后 left.size() < rgiht.size(),那么就不符合我们上述的定义了,还需要将 right.poll() 放入 left
    • 如果 out > left.peek(),说明它在right,需要将它从right移除。同理这样也不行,它会出现一个问题如果移除之后 left.size() > rgiht.size() + 1,那么也不符合我们上述的定义,需要将 left.poll() 放入 right
    • 最后,left的堆顶元素(1/2个) 就是该滑窗的中位数

滑窗中位数有了,接下来就是计算——将窗口中元素全部变为中位数所需的操作次数,画个图好理解:
在这里插入图片描述
得到 r e s res res 数组(res[i]:将 [i,i+k-1] 所有数变成中位数的操作次数)之后,剩下的就是枚举选哪 k k k 个不重叠的子数组,直接使用 dp 来做,定义 f[i][j]:在前 j 个数中,选择 i 个长度为 x 的不重叠子数组所需的最小操作次数

  • 对于f[i][j],即以下标为 j-1 结尾的子数组有选或不选两种情况:
  • 不选,它直接从 f[i][j-1] 转移过来,f[i][j] = f[i][j-1]
  • 选,题目要求它不能重叠,所以选的子数组下标是[j-k,j-1],需要从 f[i-1][j-k](这里j-k表示的是前 j-k 个数,也就是 [0,j-k-1] 选 i-1 个数的最小操作次数) 转移过来,f[i][j] = f[i-1][j-k] + res[j-k]

代码如下:

class Solution {public long minOperations(int[] nums, int x, int k) {long[] res = medianSlidingWindow(nums, x);//[i, i + x - 1]int n = nums.length;long[][] f = new long[k+1][n+1];// f[i][j] = min(f[i][j-1], f[i-1][j-x] + res[j-x])for(int i = 1; i <= k; i++){f[i][i*x-1] = Long.MAX_VALUE;for(int j = i * x; j <= n - (k - i) * x; j++){f[i][j] = Math.min(f[i][j-1], f[i-1][j-x] + res[j-x]);}}return f[k][n];}public long[] medianSlidingWindow(int[] nums, int k) {int n = nums.length;long[] ans = new long[n-k+1];LazyHeap left = new LazyHeap((x, y) -> Integer.compare(y, x));LazyHeap right = new LazyHeap((x, y) -> Integer.compare(x, y));for(int l = 0, r = 0; r < n; r++){int in = nums[r];// 入堆操作if(left.size() == right.size()){left.push(right.pushPop(in));}else{right.push(left.pushPop(in));}if(r < k - 1) continue;int x = left.top();// 计算变成中位数所需操作次数ans[l] = (long) x * (k % 2) + right.sum() - left.sum();int out = nums[l];// 出堆操作if(out <= left.peek()){left.remove(out);if(left.size() < right.size()){left.push(right.pop());}}else{right.remove(out);if(left.size() > right.size() + 1){right.push(left.pop());}}l++;}return ans;}
}
// 手写的懒删除堆(否则会超时)
class LazyHeap extends PriorityQueue<Integer> {//统计当前每个元素需要删除次数private final Map<Integer, Integer> removeCnt = new HashMap<>();//实际堆的大小private int size = 0;private long sum = 0;public LazyHeap(Comparator<Integer> comparator){super(comparator);}public int size(){return size;}public long sum(){return sum;}//懒删除操作public void remove(int x){removeCnt.merge(x, 1, Integer::sum);size--;sum -= x;}//实际执行删除操作private void applyRemove(){while(removeCnt.getOrDefault(peek(), 0) > 0){removeCnt.merge(poll(), -1, Integer::sum);}}//查看推顶元素public int top(){applyRemove();return peek();}//出堆public int pop(){applyRemove();size--;sum -= peek();return poll();}//入堆public void push(int x){int c = removeCnt.getOrDefault(x, 0);if(c > 0){removeCnt.put(x, c - 1);}else{offer(x);}sum += x;size++;}//push(x), pop()public int pushPop(int x){applyRemove();sum += x;offer(x);sum -= peek();return poll();}
}
http://www.dtcms.com/wzjs/597277.html

相关文章:

  • 网站开发需求文档prd模板WordPress快速发布文章
  • wordpress站长之家贵阳58同城做网站公司
  • 网站微商城的建设运营实践和思考网站增加流量
  • 虚拟网站怎么做的搭建电商平台网站
  • 武夷山网站设计网站广告收费标准
  • 最早的做团购的网站网站开发模板系统
  • 青海网站 建设网页传奇国度
  • 东莞凤岗网站制作蜘蛛网站长工作职责
  • 有哪些做壁纸的网站好网站建设整个流程
  • .jsp网站开发技术wordpress 房产插件
  • 湖南做网站的公司排名最新网站建设软件
  • 如何申请域名做网站郑州电力高等专科学校
  • 在哪家网站做淘宝客最好手机网站开发怎么样
  • 网站建设网页与数据库连接网页布局设计类型
  • 西安私人网站高端网站建设价钱
  • 室内设计网站资源全球网站建设品牌
  • 商务咨询公司网站制作模板数据库网站建设多少钱
  • 网站上传大文件合肥做网站建设公司
  • 网站备案app开发公司与物业公司移交协议
  • 网站建设吗5年的室内设计师收入
  • 成品网站app开发简述传统营销与网络营销的整合
  • 织梦网站数据库备份文件夹网站设计照着做 算侵权吗
  • 高端品牌网站开发网站建设运营知识
  • 商城网站建设的优势WordPress仿牌
  • 品牌网站建设e小蝌蚪七台河新闻视频
  • 找人做网站需要注意什么如何给别人做网站挣钱
  • 七台河网站建设深圳知名设计公司有哪些
  • 网站开发设计实训实训总结wap网站怎么发布
  • 长沙网站搭建公司联系方式网站建设私单合同
  • 网站的劣势哈尔滨网络公司资讯