原创公众号:bigsai 如果不错记得点赞收藏!
关注回复 bigsai 领取Java进阶pdf资源,回复进群加入力扣打卡群。
上周打卡内容:43字符串相乘&44通配符匹配 45跳跃游戏&46全排列

全排列Ⅱ

给定一个可包含重复数字的序列,返回所有不重复的全排列。

示例:

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

法一 哈希
这题相比之前的就是有重复的情况,最笨的方法就是用哈希将各种序列存到Set中最后返回,但是这也是一种方法和策略:

 Set<String>set=new HashSet<String>();public List<List<Integer>> permuteUnique(int[] nums) {List<List<Integer>> list=new ArrayList<List<Integer>>();Arrays.sort(nums);arrange(nums, 0, nums.length-1, list);return list;}private void arrange(int[] nums, int start, int end, List<List<Integer>> list) {if(start==end){List<Integer>list2=new ArrayList<Integer>();StringBuilder sBuilder=new StringBuilder();for(int a:nums){sBuilder.append(a);list2.add(a);}if(!set.contains(sBuilder.toString())){list.add(list2);  set.add(sBuilder.toString());}}for(int i=start;i<=end;i++){swap(nums,i,start);arrange(nums, start+1, end, list);swap(nums, i, start);}}private void swap(int[] nums, int i, int j) {int team=nums[i];nums[i]=nums[j];nums[j]=team;}

但是效果比较差:

法二 递归剪枝

第一个是真的很慢,但是有什么可以优化的方案吗?答案当然是有的,我们在执行递归全排列的时候,主要考的是要把重复的情况搞下去,怎么思考这个问题呢?

我们在进行交换swap的时候从前往后,前面的确定之后就不会在动,所以我们要慎重考虑和谁交换。剩下所有数默认不重复会排列所有情况,所以1 2 33 2 1在这个问题上等价,但是1 1 2 3第一个数有三种情况而不是四种情况

1 1 2 3
2 1 1 3
3 1 2 1

另外比如3 1 1,3和自己交换,和后面两个1只能和其中一个进行交换,我们这里可以约定和第一个出现的进行交换,我们看一个图解部分过程:

所以,当我们从一个index开始的时候要记住以下的规则:同一个数只交换一次(包括自己的数)。
在判断的时候,你可以遍历,也可以使用hashSet().

具体实现的代码为:


public List<List<Integer>> permuteUnique(int[] nums) {List<List<Integer>> list=new ArrayList<List<Integer>>();arrange(nums, 0, nums.length-1, list);return list;}private void arrange(int[] nums, int start, int end, List<List<Integer>> list) {if(start==end){List<Integer>list2=new ArrayList<Integer>();for(int a:nums){list2.add(a);}list.add(list2);}Set<Integer>set=new HashSet<Integer>();   for(int i=start;i<=end;i++){if(set.contains(nums[i]))continue;set.add(nums[i]);             swap(nums,i,start);arrange(nums, start+1, end, list);swap(nums, i, start);}
}
private void swap(int[] nums, int i, int j) {int team=nums[i];nums[i]=nums[j];nums[j]=team;
}

法三 回溯剪枝
我是压根没考虑用回溯,因为回溯完整的比直接递归慢,但是这里用回溯剪枝比较好,剪枝条的规则如下:

  • 先对序列进行排序
  • 试探性将数据放到当前位置
    • 如果当前位置数字已经被使用,那么不可使用
    • 如果当前数字和前一个相等但是前一个没有被使用,那么前当前不能使用,需要使用前一个数字。

思路很简单,实现起来也很简单:

List<List<Integer>> list;
public List<List<Integer>> permuteUnique(int[] nums) {list=new ArrayList<List<Integer>>();List<Integer> team=new ArrayList<Integer>();boolean jud[]=new boolean[nums.length];Arrays.sort(nums);dfs(jud, nums, team, 0);return list;
}
private  void dfs(boolean[] jud, int[] nums, List<Integer> team, int index) {// TODO Auto-generated method stubint len = nums.length;if (index == len)// 停止{list.add(new ArrayList<Integer>(team));} elsefor (int i = 0; i < len; i++) {if (jud[i]||(i>0&&nums[i]==nums[i-1]&&!jud[i-1])) //当前数字被用过 或者前一个相等的还没用,当前即不可用continue;team.add(nums[i]);jud[i]=true;dfs(jud, nums, team, index + 1);jud[i] = false;// 还原team.remove(index);}
}

旋转图像

题目描述:

给定一个 n × n 的二维矩阵表示一个图像。
将图像顺时针旋转 90 度。
说明:
你必须在原地旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要使用另一个矩阵来旋转图像。

示例 1:

给定 matrix =
[
[1,2,3],
[4,5,6],
[7,8,9]
],
原地旋转输入矩阵,使其变为:
[
[7,4,1],
[8,5,2],
[9,6,3]
]

示例 2:

给定 matrix =
[
[ 5, 1, 9,11],
[ 2, 4, 8,10],
[13, 3, 6, 7],
[15,14,12,16]
],
原地旋转输入矩阵,使其变为:
[
[15,13, 2, 5],
[14, 3, 4, 1],
[12, 6, 8, 9],
[16, 7,10,11]
]

这题思路可能比较清晰,但实现起来磕磕绊绊的地方可能比较多。每个人按照自己的思维找到一个好的方法就可以了,我把我自己的方法分享一下:

首先要看到重要信息:

  • n*n的矩阵
  • 不可创建新的矩阵
  • 顺时针旋转

旋转其实就是一个中心对称问题找点的问题,我们可以将这个矩阵分为任意四部分,其中一个部分某个点作为起始点开始交换操作。明显看的出来是左开右闭的操作。

在具体确定好(i,j)后,找到对应其他三个点的坐标。坐标其实也是很有规律的,需要自己相通就行,这里就不带大家推导了,点和对面的点中点是矩阵中心,可以进行验算。

实现代码为:

public void rotate(int[][] matrix) {int len=matrix.length;for(int i=0;i<len/2;i++)//第i行{int team=0;for(int j=i;j<len-i-1;j++)//每个数进行四次操作{int x1=i,y1=j;int x2=j,y2=len-i-1;int x3=len-i-1,y3=len-j-1;int x4=len-j-1,y4=i;team=matrix[x1][y1];matrix[x1][y1]=matrix[x4][y4];matrix[x4][y4]=matrix[x3][y3];matrix[x3][y3]=matrix[x2][y2];matrix[x2][y2]=team;}}}

结语:好了今天就到这里了,欢迎关注原创技术公众号:【bigsai】,回复进群加笔者微信一起加入打卡!

LeetCode 47全排列Ⅱ48旋转图像相关推荐

  1. LeetCode 47. 全排列 II

    文章目录 解法1:回溯 + 剪枝 牛客网的全排列 https://leetcode-cn.com/problems/permutations-ii/ 难度:中等   给定一个可包含重复数字的序列,返回 ...

  2. leetcode 47. 全排列 II 思考分析

    题目 给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列. 思考分析以及代码 这一题和前面的做过的两个题目有所关联: leetcode 46. 全排列 思考分析 再加上lee ...

  3. [LeetCode]47. 全排列 II

    47. 全排列 II 难度中等761收藏分享切换为英文接收动态反馈 给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列. 示例 1: 输入:nums = [1,1,2] 输出 ...

  4. LeetCode 47. 全排列 II【数组,回溯算法,排序去重】

    47. 全排列 II 给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列. 示例 1: 输入:nums = [1,1,2] 输出: [[1,1,2], [1,2,1], [2 ...

  5. LeetCode 47 全排列 II -- 回溯法

    来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/permutations-ii 题意: 给定一个可包含重复数字的序列 nums ,按任意顺序 返 ...

  6. LeetCode 47. 全排列 II(回溯+搜索剪枝)

    文章目录 1. 题目信息 2. 解题 1. 题目信息 给定一个可包含重复数字的序列,返回所有不重复的全排列. 示例:输入: [1,1,2] 输出: [[1,1,2],[1,2,1],[2,1,1] ] ...

  7. Leetcode 47. 全排列 II (每日一题 20211015)

    给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列.示例 1:输入:nums = [1,1,2] 输出: [[1,1,2],[1,2,1],[2,1,1]] 示例 2:输入: ...

  8. LeetCode 47 全排列 II

    题目描述 给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列. 题解 注意这里只有在不相等的时候才进行交换. 代码 class Solution {public:vector ...

  9. 2022-2-23 Leetcode 47.全排列 II

    重点在于剪枝,这个和 组合总和 的剪枝类似. class Solution {vector<int> vis;public:void backtrack(vector<int> ...

最新文章

  1. 鸿蒙兼容安卓app 为什么还要生态,就因为鸿蒙兼容安卓APP,中兴就宣布弃用?...
  2. IT人不要一直做技术[转载]
  3. Zipline Development Guidelines
  4. 三天没有更新我的BLOG
  5. 基于TFS实践敏捷-可视化管理
  6. docker设置http_proxy https_proxy解决gcr.io/kaniko-project/executor:v1.7.0之类的镜像拉取问题
  7. Spark _27_自定义函数UDF和UDAF
  8. PSIM软件学习---04 子电路的创建
  9. 如何在不卸载的情况下暂时禁用Tuxera NTFS
  10. XML揭秘 入门 应用 精通pdf
  11. 【优化调度】基于matlab人工鱼群算法求解梯级水库调度优化问题【含Matlab源码 415期】
  12. java实现行政区域划分_JAVA采集京东的全国行政区划数据
  13. 初学者怎样看懂python代码_初学者怎样看懂代码?
  14. 优动漫PAINT入门宝典(图层篇)——矢量图层
  15. c# 连接 oracle数据库字符集为us7ascii的问题,实验了好几个方案 成功了
  16. linux 批量convert,使用convert来批量处理图片
  17. origin python控制台怎么用_如何在标准python控制台中访问BPY?BPY是python的混合器...
  18. 人工智能实践作业-修道士和野人过河问题
  19. 我的世界神秘时代安卓java版_我的世界神秘时代4
  20. [附源码]Python计算机毕业设计Django的高校资源共享平台

热门文章

  1. 石墨烯区块链(4)API
  2. 347. 前 K 个高频元素(哈希表)
  3. [hypervisor]-ARMV8的hypervisor技术介绍–InProgress
  4. optee3.8 qemu_v8的环境搭建篇
  5. 合并odex和少dex的apk为完整的apk文件
  6. dft变换的两幅图_快速傅里叶变换FFT计算方法 原理及公式
  7. JAVA md5加密的工具类
  8. 16、Event事件(定时任务)是什么?
  9. Java多线程的实现方式-Thread 类,Runnable 接口
  10. Python之网络图片爬取