KamaCoder(一)

题目来源于:卡码网KamaCoder

题解来源于:GitHub - youngyangyang04/kamacoder-solutions: 卡码网题解全集 

字符串解压缩

给定一个被压缩过的字符串,压缩规则如下: 对于字符串中连续的m个相同字符串S将会压缩为[m|S](m为一个整数且0<=m<=100),例如字符串ABCABCABC将会被压缩为[3|ABC]。 

你的任务是解压被压缩过的字符串。

样例输入 

"HG[3|B[2|CA]]F"

样例输出 

"HGBCACABCACABCACAF"
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Scanner;

/**
 * @author light
 * @Description  字符串解压缩
 *
 * 给定一个被压缩过的字符串,压缩规则如下:
 * 对于字符串中连续的m个相同字符串S将会压缩为[m|S](m为一个整数且0<=m<=100),
 * 例如字符串ABCABCABC将会被压缩为[3|ABC]。
 * 你的任务是解压被压缩过的字符串。
 *
 * (思路:利用栈/指针(利用递归的思想
 * @create 2023-08-17 4:53
 */
public class n1 {
	public static void main(String[] args) {
		Scanner input=new Scanner(System.in);
		String s=input.nextLine(); //考虑字符串中有空格的情况

		//我的思路:利用栈:卡玛网两个案例未通过   通过案例数:7/9  待解决
		//s=stringDecompression(s);
        //卡玛网题解
		s=decode(s)
		System.out.println(s);
	}

        //利用栈
	public static String stringDecompression(String s){
		Deque<Character> stack=new ArrayDeque<>();
		if(s==null){
			return "";
		}
		for (int i = 0; i < s.length(); i++) {
			char ch=s.charAt(i);
			if (ch!=']'){
				stack.push(ch);
			}else{
				Deque<Character> stackOut=new ArrayDeque();
				while(stack.peek()!='|'){
					stackOut.push(stack.pop());
				}
				stack.pop(); //出栈的是'|'
				int count=stack.pop()-'0';
				StringBuilder sb=new StringBuilder();
				while(!stackOut.isEmpty()){
					sb.append(stackOut.removeLast());
				}
				String s1=sb.toString();
				StringBuilder sb1=new StringBuilder();
				for(int j=1;j<=count;j++){
					sb1.append(s1); //解压缩
				}
				 s1=sb1.toString();
				for (int j = 0; j < s1.length(); j++) {
					char c=s1.charAt(j);
					stackOut.push(c);
				}
				if(stack.pop()=='['){
					while(!stackOut.isEmpty()){
						stack.push(stackOut.pop());
					}
				}
			}
		}
		StringBuilder sb=new StringBuilder();
		while(!stack.isEmpty()){
			sb.append(stack.removeLast());
		}
		return sb.toString();
	}

        //利用递归
	public static String decode(String s){
		int x=-1,y=-1,z=-1;
		int i=0;
		//第一次递归找最里面的三个分隔符
		while(i<s.length()){
			if(s.charAt(i)=='['){
				x=i;
			} else if (s.charAt(i)=='|') {
				y=i;
			} else if (s.charAt(i)==']') {
				z=i;
				break;
			}
			i++;
		}
		if(x!=-1&&y!=-1&&z!=-1){
			int items= Integer.parseInt(s.substring(x+1,y));
			String sub=s.substring(y+1,z);
			StringBuilder sb=new StringBuilder();
			for (int j = 1; j <=items ; j++) {
				sb.append(sub);
			}
			String decodeStr=s.substring(0,x)+sb.toString()+s.substring(z+1);
			return decode(decodeStr);
		}
		return s;
	}
}

子矩形的最大面积

给定一个矩形,宽度为 W,高度为 H,现需要对其进行划分。现有一个数组 yCutting 用于表示在水平方向上用于切分矩形的切线位置,另有一个数组 xCutting 表示在垂直方向上用于切分矩形的切线位置。

求被切割后的所有子矩形中最大的那块的面积。

输入

第一行 H:矩形的高度 

第二行 W:矩形的宽度 

第三行:yCutting 数组的长度 

第四行:yCutting 数组 

第五行:xCutting 数组的长度 

第六行:xCutting 数组

输出

一个整数,表示最大的那块子矩形的面积。

样例输入 

5
4
3
1 2 4
2
1 3

样例输出 

4
import java.util.Arrays;
import java.util.Scanner;

/**
 * @author light
 * @Description 子矩形的最大面积

 *(思路:首先读取输入数据,然后对水平和垂直切割数组进行排序,并
 * 利用辅助函数 getMaxInterval 计算每个方向上切割区间的最大值。
 * 最终,将两个方向上的最大切割区间相乘即得到最大子矩形的面积。
 * @create 2023-08-17 6:03
 */
public class n3 {
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		//获取矩形高度
		int h=input.nextInt();
		//获取矩形宽度
		int w=input.nextInt();
		//yCutting 数组的长度及内容
		int y= input.nextInt();
		int[] yCutting=new int[y];
		for (int i = 0; i < y; i++) {
			yCutting[i]=input.nextInt();
		}
		//xCutting 数组的长度及内容
		int x= input.nextInt();
		int[] xCutting=new int[x];
		for (int i = 0; i < x; i++) {
			xCutting[i]=input.nextInt();
		}

		//对切割点进行排序
		Arrays.sort(yCutting);
		Arrays.sort(xCutting);

		//获取水平切割区间最大值
		int maxYInterval=getMaxInterval(yCutting,w);
		//获取垂直切割区间最大值
		int maxXInterval=getMaxInterval(xCutting,h);
		//计算最大子矩形面积
		int maxArea=maxXInterval*maxYInterval;

		System.out.println(maxArea);


	}

	private static int getMaxInterval(int[] cuttingArray, int dimension) {
		int interval=cuttingArray[0]; //获取首边界到第一条割线的距离
		for (int i = 1; i < cuttingArray.length; i++) {
			interval=Math.max(interval,cuttingArray[i]-cuttingArray[i-1]);
		}

		//dimension-cuttingArray[cuttingArray.length-1]:最后一条割线到尾边界的距离
		interval=Math.max(interval,dimension-cuttingArray[cuttingArray.length-1]);
		return interval;
	}
}

逛街

小明在周末的时候和他的小伙伴来到大城市逛街,一条步行街上有很多高楼,共有 n 座高楼排成一行。 

小明从第一栋一直走到了最后一栋,小明从来都没有见到这么多的楼,所以他想知道他在每栋楼的位置处能看到多少栋楼呢?(当前面的楼的高度大于等于后面的楼时,后面的楼将被挡住)

输入

输入一个数组,表示每栋楼的高度。

输出

输出一个数组,表示在每栋楼对应的位置上能看到多少栋楼。

样例输入 

[5,3,8,3,2,5]

样例输出 

[3,3,5,4,4,4]
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Deque;
import java.util.Scanner;

/**
 * @author light
 * @Description 逛街
 *
 *
 * (思路:
 * 题目中要求从两个方向看,从左向右遍历和从右向左遍历,考虑使用单调栈
 * 首先定义一个数组存放结果;将 visibleCounts 每个位置上的值加 1(因为包括自己本身的楼)。
 * **从左向右遍历高楼时,定义一个栈stack1,栈中存放已经经过的高楼,保证栈顶元素始终比后面元素高;
 * 遍历过程中,对于每一栋楼,将当栈中大小加到对应楼visibleCounts的下标处;表示向左看的楼数
 *
 * **从右向左遍历高楼时,定义一个栈stack2,栈中存放已经经过的高楼,保证栈顶元素始终比后面元素高;
 * 遍历过程中,对于每一个元素,将当前栈的大小加到对应楼visibleCounts的下标出,表示向右看的楼数
 * @create 2023-08-17 6:04
 */
public class n4 {
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		//String[] buildings = input.next().split(",");
		//int[] height=new int[buildings.length];
		//for (int i = 0; i < height.length; i++) {
		//	height[i]=Integer.parseInt(buildings[i]);
		//}
		String buildings=input.next();
		int[] height=parseIntArray(buildings);
		int[] visibleCounts=new int[height.length];
		Arrays.fill(visibleCounts,1); //先自加1,表示楼本身
		findVisibleCounts(height,visibleCounts);
		System.out.println(Arrays.toString(visibleCounts).replaceAll(" ",""));

	}


	public static void findVisibleCounts(int[] height,int[] visibleCounts){
		Deque<Integer> stack1=new ArrayDeque<>(); //存放从左向右遍历的楼数:表示向左看
		Deque<Integer> stack2=new ArrayDeque<>();//存放从右向左遍历的楼数:表示向右看
		for (int i = 0; i < height.length; i++) {
			visibleCounts[i]+=stack1.size();
			while(!stack1.isEmpty()&&stack1.peek()<=height[i]){
				stack1.pop();
			}
			stack1.push(height[i]);
		}

		for (int i = height.length-1; i >=0 ; i--) {
			visibleCounts[i]+=stack2.size();
			while(!stack2.isEmpty()&&stack2.peek()<=height[i]){
				stack2.pop();
			}
			stack2.push(height[i]);
		}
	}
	private static int[] parseIntArray(String buildings) {
		String[] s=buildings.substring(1,buildings.length()-1).split(",");
		int[] height=new int[s.length];
		for (int i = 0; i < height.length; i++) {
			height[i]=Integer.parseInt(s[i].trim());
		}
		return height;
	}


}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值