7.3 重新写的
class Solution {
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
boolean[] flag = new boolean[nums.length];
helper(nums, res, 0, new ArrayList<>(), flag);
return res;
}
private static void helper(int[] nums, List<List<Integer>> res, int index, ArrayList<Integer> list, boolean[] flag) {
if (index == nums.length) {
res.add(new ArrayList<>(list));
return;
}
for (int i = 0; i < nums.length; i++) {
if (flag[i] == false) {
flag[i] = true;
list.add(nums[i]);
helper(nums, res, index + 1, list, flag);
list.remove(list.size() - 1);
flag[i] = false;
}
}
}
}
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
if(strs==null || strs.length==0) return new ArrayList();
Map<String,List> map = new HashMap<>();
for(String s :strs){
char[] cur = s.toCharArray();
Arrays.sort(cur);
String key = String.valueOf(cur);
if(! map.containsKey(key)){
map.put(key,new ArrayList());
}
map.get(key).add(s);
}
return new ArrayList(map.values());
}
}
这道题,一看子序列和,想动态规划,dp【】,这个考虑的就是dp[ i ] = Math.max(dp[i-1]+nums[i],nums[i]),然后因为dp[n] 存的不一定就是最长区间,因为最长区间可能在中间,所以需要一个max每次对比一下,还有dp其实只存了前一个值,所以替换成一个变量就可。
class Solution {
public static int maxSubArray(int[] nums) {
if(nums == null || nums.length==0) return 0;
int maxNum = nums[0];
int curmax = 0;
for(int i=0;i<nums.length;i++){
curmax = Math.max(curmax+nums[i],nums[i]);
maxNum = Math.max(maxNum,curmax);
}
return maxNum;
}
}
给定一个非负整数数组,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个位置。
示例 1:
输入: [2,3,1,1,4]
输出: true
解释: 我们可以先跳 1 步,从位置 0 到达 位置 1, 然后再从位置 1 跳 3 步到达最后一个位置。
示例 2:
输入: [3,2,1,0,4]
输出: false
解释: 无论怎样,你总会到达索引为 3 的位置。但该位置的最大跳跃长度是 0 , 所以你永远不可能到达最后一个位置。
从后往前遍历数组,如果遇到的元素可以到达最后一行,则截断后边的元素。否则继续往前,弱最后剩下的元素大于1个,则可以判断为假。否则就是真,时间复杂度O(n)就可以,不知道有没有大佬可以继续优化。
class Solution {
public boolean canJump(int[] nums) {
if(nums==null || nums.length == 0) return false;
int n = 1;
for(int i = nums.length-2;i>=0;i--){
if(nums[i] >= n){
n=1;
}
else{
n++;
}
if(i==0 && n>1){
return false;
}
}
return true;
}
}
给出一个区间的集合,请合并所有重叠的区间。
示例 1:
输入: [[1,3],[2,6],[8,10],[15,18]]
输出: [[1,6],[8,10],[15,18]]
解释: 区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
示例 2:
输入: [[1,4],[4,5]]
输出: [[1,5]]
解释: 区间 [1,4] 和 [4,5] 可被视为重叠区间。
for (int i = 0; i < res.length; i++) {
System.out.println(Arrays.toString(res[i]));
}
自定义排序:
Arrays.sort(intervals, new Comparator<int[]>() {
@Override
public int compare(int[] a, int[] b) {
return a[0] - b[0];
}
});
list转int【】【】 你你
return list.toArray(new int[list.size()][]);
public class merge56 {
public static void main(String[] args) {
int[][] nums = {{1, 3}, {2, 6}, {8, 10}, {15, 18}};
int[][] res = merge(nums);
for (int i = 0; i < res.length; i++) {
System.out.println(Arrays.toString(res[i]));
}
}
public static int[][] merge(int[][] intervals) {
if (intervals == null || intervals.length == 0 || intervals[0].length==0) return new int[0][0];
Arrays.sort(intervals, new Comparator<int[]>() {
@Override
public int compare(int[] a, int[] b) {
return a[0] - b[0];
}
});
List<int[]> list = new ArrayList<>();
list.add(intervals[0]);
for (int i = 1; i < intervals.length; i++) {
int[] curNum = intervals[i];
int[] peek = list.get(list.size() - 1);
if (curNum[0] > peek[1]) {
list.add(curNum);
} else {
peek[1] = Math.max(peek[1], curNum[1]);
}
}
return list.toArray(new int[list.size()][]);
}
}
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。
问总共有多少条不同的路径?
7.4 自己写的
class Solution {
public int uniquePaths(int m, int n) {
if(m<=0 || n<=0) return 0;
int[][] dp=new int[m][n];
for(int i=0;i<n;i++) dp[0][i]=1;
for(int i=0;i<m;i++) dp[i][0]=1;
for(int i=1;i<m;i++){
for(int j=1;j<n;j++){
dp[i][j]=dp[i-1][j]+dp[i][j-1];
}
}
return dp[m-1][n-1];
}
}
**一维数组dp【】 **想法:
class Solution {
public int uniquePaths(int m, int n) {
if(m<=0 || n<=0) return 0;
int[] dp=new int[n];
Arrays.fill(dp, 1);
for(int i=1;i<m;i++){
for(int j=1;j<n;j++){
dp[j]+=dp[j-1];
}
}
return dp[n-1];
}
}
如果有障碍呢?lee63
如果碰到1就dp[ ]=0;
分为四种情况
:
public class minPathSum64 {
public static void main(String[] args) {
int[][] grid = {
{1,3,1},
{1,5,1},
{4,2,1}
};
int res = minPathSum(grid);
System.out.println(res);
}
public static int minPathSum(int[][] grid) {
int m = grid.length,n=grid[0].length;
if(grid==null || m==0 || n==0) return 0;
int[][] dp = new int[m][n];
dp[0][0] = grid[0][0];
for(int i=1;i<m;i++){
dp[i][0]=grid[i][0]+dp[i-1][0];
}
for(int i=1;i<n;i++){
dp[0][i]=grid[0][i]+dp[0][i-1];
}
for(int i=1;i<m;i++){
for(int j=1;j<n;j++){
dp[i][j] = Math.min(dp[i-1][j],dp[i][j-1])+grid[i][j];
}
}
return dp[m-1][n-1];
}
}
class Solution {
public int minPathSum(int[][] grid) {
if(grid.length==0|| grid==null) return 0;
int[] dp=new int[grid[0].length];
for(int i=grid.length-1;i>=0;i--){
for(int j=grid[0].length-1; j>=0; j--){
if( j != grid[0].length-1 && i!=grid.length-1){
dp[j]= Math.min( dp[j], dp[j+1] ) + grid[i][j];
}
else if(i==grid.length-1 && j!=grid[0].length-1){
dp[j]=grid[i][j]+dp[j+1];
}
else if(i!=grid.length-1 && j==grid[0].length-1){
dp[j]=grid[i][j]+dp[j];
}
else
dp[j]=grid[i][j];
}
}
return dp[0];
}
}
class Solution {
public int climbStairs(int n) {
if(n<=0) return 0;
if(n == 1) return 1;
if(n == 2) return 2;
int p1 = 1,p2 = 2;
int p3=0;
for(int i=3;i<=n;i++){
p3 = p1+p2;
p1=p2;
p2=p3;
}
return p3;
}
}
给你两个单词 word1 和 word2,请你计算出将 word1 转换成 word2 所使用的最少操作数 。
你可以对一个单词进行如下三种操作:
插入一个字符
删除一个字符
替换一个字符
示例 1:
输入:word1 = “horse”, word2 = “ros”
输出:3
解释:
horse -> rorse (将 ‘h’ 替换为 ‘r’)
rorse -> rose (删除 ‘r’)
rose -> ros (删除 ‘e’)
示例 2:
7.4
public class minDistance72 {
public static void main(String[] args) {
String word1 = "horse", word2 = "ros";
int res = minDistance(word1, word2);
System.out.println(res);
}
public static int minDistance(String word1, String word2) {
int m = word1.length(), n = word2.length();
if (m == 0) return n;
if (n == 0) return m;
int[][] dp = new int[m+1][n+1];
// 先收拾边界
for(int i=0;i<=m;i++){// 注意这里要有=m
dp[i][0] = i;
}
for(int i = 0;i<=n;i++){
dp[0][i] = i;
}
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
if(word1.charAt(i-1) == word2.charAt(j-1)){// 注意这里是i-1
dp[i][j] = dp[i-1][j-1];
}
// 别忘最后+1
else dp[i][j] = minhelper(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1])+1;
}
}
return dp[m][n];
}
private static int minhelper(int i, int i1, int i2) {
return Math.min(i,Math.min(i1,i2));
}
}