Leetcode每天五题-04

  1. 字母异位词分组

给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串。

示例:

输入: [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”],
输出:
[
[“ate”,“eat”,“tea”],
[“nat”,“tan”],
[“bat”]
]

说明:

所有输入均为小写字母。
不考虑答案输出的顺序。

备注:

思路就是对异位词进行hash计算,使它们能计算出一个相同的key来

	public static List<List<String>> groupAnagrams(String[] strs) {

		if (strs == null || strs.length == 0) {
			return null;
		}
		HashMap<String, List<String>> map = new HashMap<>();
		int count[] = new int[26];
		for (String str : strs) {
			Arrays.fill(count, 0);
			for (char c : str.toCharArray()) {
				count[c - 97]++;
			}
			// 替换所有非数字字符,非必须
			String key = Arrays.toString(count).replaceAll("\\D", "");
			if (!map.containsKey(key)) {
				map.put(key, new ArrayList<>());
			}
			map.get(key).add(str);
		}

		return new ArrayList<>(map.values());
	}

讨论区

在美版leetcode上看到大神的思路,用质数表示26个字母,把字符串的各个字母相乘,这样可保证字母异位词的乘积必定是相等的。其余步骤就是用map存储。

  1. 最大子序和

给定一个整数数组nums,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

示例:

输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
进阶:

class Solution {
	public int maxSubArray(int[] nums) {
		if (nums == null || nums.length == 0) {
			return 0;
		}
		int ans = nums[0];
		for (int i = 1; i < nums.length; i++) {
			nums[i] += Math.max(nums[i - 1], 0);
			ans = Math.max(ans, nums[i]);
		}
		return ans;
	}
}
class Solution {
	public int maxSubArray(int[] nums) {
		if (nums == null || nums.length == 0) {
			return 0;
		}
		int sum, tmpSum;
		tmpSum = nums[0];
		sum = nums[0];
		for (int i = 1; i < nums.length; i++) {
			tmpSum = tmpSum > 0 ? tmpSum + nums[i] : nums[i];
			sum = Math.max(sum, tmpSum);
		}
		return sum;
	}
}
  1. 合并区间
    给出一个区间的集合,请合并所有重叠的区间。

示例 1:

输入: [[1,3],[2,6],[8,10],[15,18]]
输出: [[1,6],[8,10],[15,18]]
解释: 区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].

备注:

耗时比较久,68ms

public static List<Interval> merge(List<Interval> intervals) {
	if (intervals == null || intervals.size() == 0) {
		return intervals;
	}
	// 先按start排序
	intervals.sort((la, lb) -> la.start - lb.start);
	Interval pre = intervals.get(0);
	Interval cur = null;
	for (int i = 1; i < intervals.size();) {
		cur = intervals.get(i);
		// 不能合并
		if (cur.start > pre.end) {
			pre = cur;
			// 重要
			i++;
		} else {
			pre.end = Math.max(pre.end, cur.end);
			intervals.remove(i);
		}
	}
	return intervals;
}
  1. 不同路径

一个机器人位于一个m x n 网格的左上角。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角,问总共有多少条不同的路径?

备注:

…没看出来这是组合数

带空间压缩版本

class Solution {
		public int uniquePaths(int m, int n) {
			int[] dp = new int[n];
			for (int i = 0; i < m; i++) {
				for (int j = 0; j < n; j++) {
					dp[j] = (i == 0 || j == 0) ? 1 : dp[j - 1] + dp[j];
				}
			}
			return dp[n - 1];
		}
	}

二维数组版本

public static int uniquePaths(int m, int n) {
	// dp[i][j]代表从0,0到i,j的方法数
	int dp[][] = new int[m][n];
	for (int i = 0; i < m; i++) {
		for (int j = 0; j < n; j++) {
			dp[i][j] = (i == 0 || j == 0) ? 1 : dp[i - 1][j] + dp[i][j - 1];
		}
	}
	return dp[m - 1][n - 1];
}
  1. 爬楼梯

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1或2个台阶。你有多少种不同的方法可以爬到楼顶呢?
注意:给定 n 是一个正整数。

示例 1:

输入: 2
输出: 2解释: 有两种方法可以爬到楼顶。

  1. 1 阶 + 1 阶
  2. 2 阶

示例 2:

输入: 3
输出: 3
解释: 有三种方法可以爬到楼顶。

  1. 1 阶 + 1 阶 + 1 阶
  2. 1 阶 + 2 阶
  3. 2 阶 + 1 阶
class Solution {
    public int climbStairs(int n) {
        int f1,f2;
        f1 = f2 = 1;
        int ans = 1;
        for(int i = 2;i<=n;i++){
            ans = f1 + f2;
            f1 = f2;
            f2 = ans;
        }
        return ans;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值