leetcode-hot100刷题第七天

一、颜色分类(leetcode-75)

问题描述

给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。
(注:不能使用代码库中排序函数)

示例

输入: [2,0,2,1,1,0]
输出: [0,0,1,1,2,2]

解法分析

本题较为常规,因为数组只有0、1、2三个元素区分,所以考虑将所有的0放在数组左边,所有的2放在数组右边,即可以得到题目要求的排序数组。具体而言,就是用前后两个指针分别探测0元素的最右边界和2元素的最左边界,用一个指针遍历一遍所给数组即可。

代码实现

public static void sortColors(int [] nums) {
		int p0 = 0;
		int p2 = nums.length-1;
		int cur = 0;
		
		int temp = 0;
		while(cur <= p2) {
			if(nums[cur] == 0) {//交换p0和cur位置元素
				temp = nums[cur];
				nums[cur] = nums[p0];
				nums[p0] = temp;
				cur++;
				p0++;
			}else if(nums[cur] == 2){//交换cur和p2的值
				temp = nums[cur];
				nums[cur] = nums[p2];
				nums[p2] = temp;
				//cur++; //考虑到左边的值之前扫描过,而与p2交换的值还未扫描过,因为不能++
				p2--;
			}else {//无交换发生,移动cur
				cur++;
			}
			
		}
	}

二、最小覆盖字串(leetcode-76)

问题描述

给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字符的最小子串。

示例

输入: S = “ADOBECODEBANC”, T = “ABC”
输出: “BANC”

解法分析

此题可以使用滑动窗口方法进行解决:即先通过增大窗口大小找到可行解,再通过缩小滑动窗口大小找到最优解。具体思路如下:

代码实现

public class Solution_76 {
	static Map<Character, Integer> ori = new HashMap<Character, Integer>(); //维护模式字符串中字符及对应个数
    static Map<Character, Integer> cnt = new HashMap<Character, Integer>(); //维护当前滑动窗口中字符及其对应个数


	public static void main(String[] args) {
		String string = "ADOBECODEBANC";
		String tString = "ABC";
		System.out.println(minWindow(string, tString));
	}
	
	public static String minWindow(String s, String t) {
		int tLen = t.length();
        for (int i = 0; i < tLen; i++) {
            char c = t.charAt(i);
            ori.put(c, ori.getOrDefault(c, 0) + 1); //将t字符串中字符和对应个数放入ori中
        }
        int l = 0, r = -1;
        int len = Integer.MAX_VALUE, ansL = -1, ansR = -1;
        int sLen = s.length();
        while (r < sLen) {
            ++r;
            if (r < sLen && ori.containsKey(s.charAt(r))) {
                cnt.put(s.charAt(r), cnt.getOrDefault(s.charAt(r), 0) + 1);//遇到符合在t字符串中的字符,将其保存在cnt中
            }
            while (check() && l <= r) { //满足是解的时候,左界限l右移
                if (r - l + 1 < len) {
                    len = r - l + 1;
                    ansL = l;
                    ansR = l + len;
                }
                if (ori.containsKey(s.charAt(l))) {
                    cnt.put(s.charAt(l), cnt.getOrDefault(s.charAt(l), 0) - 1);
                }
                ++l;
            }
        }
        return ansL == -1 ? "" : s.substring(ansL, ansR);
	}
	
	 public static boolean check() { //用于判断当前窗口是否为解
	        Iterator iter = ori.entrySet().iterator(); 
	        while (iter.hasNext()) { 
	            Map.Entry entry = (Map.Entry) iter.next(); 
	            Character key = (Character) entry.getKey(); 
	            Integer val = (Integer) entry.getValue(); 
	            if (cnt.getOrDefault(key, 0) < val) {
	                return false;
	            }
	        } 
	        return true;
	    }
}

三、子集(leetcode-78)

问题描述

给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
说明:解集不能包含重复的子集。

示例

输入: nums = [1,2,3]
输出:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]

解法分析

本题想法思路较为简单,难点应该在于怎么将简单的思考过程用程序语言优美的呈现出来。leetcode官方题解给了递归,回溯,字典排序三种解法实现。因为回溯题是本人的弱项,所以此题打算用回溯法进行思考求解。

代码实现

public class Solution_78 {
	static List<List<Integer>> output = new ArrayList();
	static int n, k;

	public static void main(String[] args) {
		int [] nums = {1,2,3};
		subsets(nums);
		System.out.println(output);
	}
	
	public static List<List<Integer>> subsets(int[] nums) {
		n = nums.length;
		for (k = 0; k < n + 1; ++k) {
			backtrack(0, new ArrayList<Integer>(), nums);
		}
		return output;
	}
	
	public static void backtrack(int first, ArrayList<Integer> curr, int[] nums) {
	    // if the combination is done
	    if (curr.size() == k)
	      output.add(new ArrayList(curr));
	    for (int i = first; i < n; ++i) {
	      // add i into the current combination
	      curr.add(nums[i]);
	      // use next integers to complete the combination
	      backtrack(i + 1, curr, nums);
	      // backtrack
	      curr.remove(curr.size() - 1);
	    }
	  }

}

四、单词搜索(leetcode-79)

问题描述

给定一个二维网格和一个单词,找出该单词是否存在于网格中。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

示例

board =
[
[‘A’,‘B’,‘C’,‘E’],
[‘S’,‘F’,‘C’,‘S’],
[‘A’,‘D’,‘E’,‘E’]
]
给定 word = “ABCCED”, 返回 true
给定 word = “SEE”, 返回 true
给定 word = “ABCB”, 返回 false

解法分析

本题考虑使用深度优先搜索算法实现,对每个吻合的点,搜寻其上下左右四个方向,找到与下一个字符匹配的路径,按该思路继续搜索,即可得到结果。

代码实现

public class Solution_79 {
	static boolean[][] marked ;
	static int[][] direction = {{-1,0},{0,-1},{0,1},{1,0}};//用于移动搜索方向
	static int m; //行数
	static int n; //列数
	
	
	public static void main(String[] args) {
		char[][] board = {
				{'A','B','C','E'},
                {'S','F','C','S'},
                {'A','D','E','E'}
		        };
		String string1 = "ABCCED";
		String string2 = "SEE";
		String string3 = "ABCB";
		System.out.println(exist(board, string1));
		System.out.println(exist(board, string2));
		System.out.println(exist(board, string3));
	}
	public static boolean exist(char[][] board, String word) {
		m = board.length;
		if(m == 0) {
			return false;
		}
		n = board[0].length;
		marked = new boolean[m][n]; //marked初始化
		
		for(int i = 0 ; i < m ; i++) {
			for(int j = 0 ; j < n ;j++) {
				if(dfs(i, j, 0, board, word)) { //使用深度优先搜索
					return true;
				}
			}
		}
		return false;
    }
	
	public static boolean dfs(int i,int j,int start,char[][] board,String word) {
		if(start == word.length() -1) {
			return board[i][j] == word.charAt(start); 
		}
		if(board[i][j] == word.charAt(start)) {
			marked[i][j] = true;
			for(int k = 0 ; k < 4 ; k++) { //遍历上下左右四个方向进行深度优先搜索
				int newX = i + direction[k][0];
				int newY = j + direction[k][1];
				if(inArea(newX, newY) && !marked[newX][newY]) {
					if(dfs(newX, newY, start+1, board, word)) {
						return true;
					}
				}
			}
			marked[i][j] = false;
		}
		return false;
	}
	
	public static boolean inArea(int x, int y) { //判断是否在边界内
		return x >= 0 && x < m && y >= 0 && y < n;
	}
}

五、柱状图中最大矩形(leetcode-84)

问题描述

给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。

示例

输入: [2,1,5,6,2,3]
输出: 10

解法分析

此题首先肯定可以用暴力法进行破解,遍历出每两个柱子形成的最大矩形面积,然后取最大值,但这样显然时间开销过大,所以我们就要想出一种更为好的解法,考虑到算法优化一般可以使用空间换时间,此题又是一维数组,所以可以考虑单调栈实现。具体思路如下:维护一个单调递增的栈,用一个数组存储某个柱子的左右边界,最后根据左右边界算的的结果更新最大矩形大小。

代码实现

public class Solution_84 {
	public static void main(String[] args) {
		int [] heights = {2,1,5,6,2,3};
		System.out.println(largestRectangleArea(heights));
	}
	public static int largestRectangleArea(int[] heights) {
		int n = heights.length;
        int[] left = new int[n]; //确定最大矩形左边界
        int[] right = new int[n]; //确定最大矩形右边界
        Arrays.fill(right, n);
        
        Stack<Integer> mono_stack = new Stack<Integer>(); //单调栈声明
        for (int i = 0; i < n; ++i) {
            while (!mono_stack.isEmpty() && heights[mono_stack.peek()] >= heights[i]) { //数组不为空且当前柱子高度小于栈顶时
                right[mono_stack.peek()] = i; //得出右边界
                mono_stack.pop(); //弹出栈顶元素
            }
            left[i] = (mono_stack.isEmpty() ? -1 : mono_stack.peek()); //左边界
            mono_stack.push(i); //入栈
        }
        
        int ans = 0;
        for (int i = 0; i < n; ++i) {
            ans = Math.max(ans, (right[i] - left[i] - 1) * heights[i]); //更新最大矩形大小
        }
        return ans;
    }
}

总结

秋招在即,也算从期末复习中走了出来,接下来几个月,踏踏实实闭关修炼,希望能在秋招有不错的收获~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
东南亚位于我国倡导推进的“一带一路”海陆交汇地带,作为当今全球发展最为迅速的地区之一,近年来区域内生产总值实现了显著且稳定的增长。根据东盟主要经济体公布的最新数据,印度尼西亚2023年国内生产总值(GDP)增长5.05%;越南2023年经济增长5.05%;马来西亚2023年经济增速为3.7%;泰国2023年经济增长1.9%;新加坡2023年经济增长1.1%;柬埔寨2023年经济增速预计为5.6%。 东盟国家在“一带一路”沿线国家中的总体GDP经济规模、贸易总额与国外直接投资均为最大,因此有着举足轻重的地位和作用。当前,东盟与中国已互相成为双方最大的交易伙伴。中国-东盟贸易总额已从2013年的443亿元增长至 2023年合计超逾6.4万亿元,占中国外贸总值的15.4%。在过去20余年中,东盟国家不断在全球多变的格局里面临挑战并寻求机遇。2023东盟国家主要经济体受到国内消费、国外投资、货币政策、旅游业复苏、和大宗商品出口价企稳等方面的提振,经济显现出稳步增长态势和强韧性的潜能。 本调研报告旨在深度挖掘东南亚市场的增长潜力与发展机会,分析东南亚市场竞争态势、销售模式、客户偏好、整体市场营商环境,为国内企业出海开展业务提供客观参考意见。 本文核心内容: 市场空间:全球行业市场空间、东南亚市场发展空间。 竞争态势:全球份额,东南亚市场企业份额。 销售模式:东南亚市场销售模式、本地代理商 客户情况:东南亚本地客户及偏好分析 营商环境:东南亚营商环境分析 本文纳入的企业包括国外及印尼本土企业,以及相关上下游企业等,部分名单 QYResearch是全球知名的大型咨询公司,行业涵盖各高科技行业产业链细分市场,横跨如半导体产业链(半导体设备及零部件、半导体材料、集成电路、制造、封测、分立器件、传感器、光电器件)、光伏产业链(设备、硅料/硅片、电池片、组件、辅料支架、逆变器、电站终端)、新能源汽车产业链(动力电池及材料、电驱电控、汽车半导体/电子、整车、充电桩)、通信产业链(通信系统设备、终端设备、电子元器件、射频前端、光模块、4G/5G/6G、宽带、IoT、数字经济、AI)、先进材料产业链(金属材料、高分子材料、陶瓷材料、纳米材料等)、机械制造产业链(数控机床、工程机械、电气机械、3C自动化、工业机器人、激光、工控、无人机)、食品药品、医疗器械、农业等。邮箱:market@qyresearch.com

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值