LeetCode第[48]题(Java):Rotate Image

题目:矩阵旋转

难度:Medium

题目内容

You are given an n x n 2D matrix representing an image.

Rotate the image by 90 degrees (clockwise).

Note:

You have to rotate the image in-place, which means you have to modify the input 2D matrix directly. DO NOT allocate another 2D matrix and do the rotation.

翻译:你有一个n*n 的2D矩阵表示一个图像。

将图像旋转90度(顺时针)。

注意:

你必须在原地旋转图像,这意味着你必须直接修改输入2D矩阵。不要分配另一个2D矩阵并进行旋转。

Example 1:

Given input matrix =
[
  [1,2,3],
  [4,5,6],
  [7,8,9]
],

rotate the input matrix in-place such that it becomes:
[
  [7,4,1],
  [8,5,2],
  [9,6,3]
]

Example 2:

Given input matrix =
[
  [ 5, 1, 9,11],
  [ 2, 4, 8,10],
  [13, 3, 6, 7],
  [15,14,12,16]
], 

rotate the input matrix in-place such that it becomes:
[
  [15,13, 2, 5],
  [14, 3, 4, 1],
  [12, 6, 8, 9],
  [16, 7,10,11]
]

我的思路:旋转90°,那就是把矩阵分为四块,只对第一块进行循环,然后用第一块的元素下标【i】【j】的表达式分别表示其他块的对应元素,然后把四个元素进行交换即可。

先将矩阵分为如下四块:

A B

C D

现在对A内元素进行循环,其元素下标表示为【i】【j】

1、将A的此元素用temp存储起来,

2、A的此元素取C区域对应的元素值,C区对应元素表示为A元素“先关于矩阵主对角线取对称,然后再取纵向中心对折”

  主对角线取对称,就是【i】【j】=》【j】【i】

  纵向中心对折,就是【i】【j】=》【n-1- i 】【j】

3、C区此元素取D区域对应的元素值,D区对应元素表示为A元素的中心对称,即“先关于横向中心对折,然后再取纵向中心对折”

  横线中心对折,就是【i】【j】=》【i】【n-1- j】

4、D区此元素取B区域对应的元素值,B区对应元素表示为A元素“先关于横向中心对折,然后再取矩阵副对角线对称”

  副对角线对称,就是【i】【j】=》【n-1-j】【n-1-i】

5、B区此元素取之前A区的值,即为 temp ,到此一轮交换结束。

需要注意的是,当矩阵的大小是偶数的时候,此时行数的对称中心 x 为对称线的上面的一个。

例如:

0

1

2

3   此时的 x = n-1 = 1,此时是需要进行交换的行范围是【0~x】,列范围也是【0~x】

  而如果是奇数,则行范围是【0~x-1】,列范围没变还是【0~x】

所以循环的时候需要注意判断奇偶,然后跳过。

我的代码:

 1     public void rotate(int[][] matrix) {
 2         int n = matrix.length;
 3         if (n <= 1) {
 4             return;
 5         }
 6
 7         int even = 1;
 8         if (matrix.length % 2 == 1) {
 9             even = 0;
10         }
11
12         int x = (n-1)/2;
13         for (int i = 0; i <= x; i++) {
14             for (int j = 0; j <= x; j++) {
15                 if (even==0 && i==x) {
16                     continue;
17                 }
18                 int temp = matrix[i][j];
19                 matrix[i][j] = matrix[n-1-j][i];
20                 matrix[n-1-j][i] = matrix[n-1-i][n-1-j];
21                 matrix[n-1-i][n-1-j] = matrix[n-1-(n-1-j)][n-1-i];
22                 matrix[n-1-(n-1-j)][n-1-i] = temp;
23             }
24         }
25     }

我的复杂度:O(N2

编码过程中的问题

1、应该使用A的元素下标【i】【j】去表示其他块所有,而不是用相对位置;

2、对“对称”“对折”的下标变化不熟悉,导致浪费不少时间;(还想了半天用 2x - i + even 来表示,其实直接 n-1-i 即可)

3、之前没考虑到矩阵奇偶对循环范围的影响,导致奇数的对称线没有交换;

4、当方法定义返回为void的时候,需要直接返回,写return就行。

答案代码

 1     public void rotate(int[][] matrix) {
 2         int n = matrix.length;
 3         if (n <= 1) {
 4             return;
 5         }
 6
 7         int x = (n-1)/2;
 8         for (int i = 0; i <= x; i++) {
 9             int[] tmp = matrix[i];
10             matrix[i] = matrix[n-1-i];
11             matrix[n-1-i] = tmp;
12         }
13
14         for (int i = 0; i < n; i++) {
15             for (int j = i+1; j < n; j++) {
16                 int temp = matrix[i][j];
17                 matrix[i][j] = matrix[j][i];
18                 matrix[j][i] = temp;
19             }
20         }
21     }

答案复杂度:O(N2

答案思路

首先将整个数组上下对称交换:

1 2 3     7 8 9
4 5 6  => 4 5 6
7 8 9     1 2 3

然后再关于主对角线对称交换:

7 8 9     7 4 1
4 5 6  => 8 5 2
1 2 3     9 6 3

优点:逻辑清晰明了

缺点:复杂度比我的方法高一点

 

扩展

逆时针旋转90°?

我的方法——ABCD块之间的取值关系会发生变化。

答案方法——有两种修改方法都行:

      a:第一步和第二步交换,即先对角线,后对折

      b:把第一步的上下对称交换改成左右对称交换,第二步不变。

原文地址:https://www.cnblogs.com/Xieyang-blog/p/9015493.html

时间: 2024-11-08 21:39:41

LeetCode第[48]题(Java):Rotate Image的相关文章

LeetCode第[26]题(Java):Remove Duplicates from Sorted Array 标签:Array

题目难度:Easy 题目: Given a sorted array, remove the duplicates in-place such that each element appear only once and return the new length. Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extr

LeetCode第[5]题(Java):Longest Palindromic Substring 标签:String、动态规划

题目中文:求最长回文子串 题目难度:Medium 题目内容: Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000. 翻译: 给定一个字符串s,找出s中最长的回文子串.你可以假设s的最大长度是1000. 什么叫回文子串? 就是字符串中,满足能正读反读都一样的子串,就是回文子串.如下所示 Input: "babad"

LeetCode第[7]题(Java):Reverse Integer 标签:数学

题目:Reverse Integer 难度:Easy 题目内容: Given a 32-bit signed integer, reverse digits of an integer. Note:Assume we are dealing with an environment which could only hold integers within the 32-bit signed integer range. For the purpose of this problem, assum

LeetCode第[42]题(Java):Trapping Rain Water

题目:接雨水 难度:hard 题目内容: Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining. The above elevation map is represented by array [0,1,0,2,1,0,1,3,2,1,2,1]. In

LeetCode第[79]题(Java):Word Search(矩阵单词搜索)

题目:矩阵单词搜索 难度:Medium 题目内容: Given a 2D board and a word, find if the word exists in the grid. The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same

LeetCode第[3]题(Java):Longest Substring Without Repeating Characters 标签:Linked List

题目中文:没有重复字符的最长子串 题目难度:Medium 题目内容: Given a string, find the length of the longest substring without repeating characters. Examples: Given "abcabcbb", the answer is "abc", which the length is 3. Given "bbbbb", the answer is &q

LeetCode第[10]题(Java):Regular Expression Matching

题目:匹配正则表达式 题目难度:hard 题目内容:Implement regular expression matching with support for '.' and '*'. '.' Matches any single character. '*' Matches zero or more of the preceding element. The matching should cover the entire input string (not partial). The fu

LeetCode第[13]题(Java):Roman to Integer

题目:罗马数字转换 题目难度:easy 题目内容:Roman numerals are represented by seven different symbols: I, V, X, L, C, D and M. Symbol Value I 1 V 5 X 10 L 50 C 100 D 500 M 1000 For example, two is written as II in Roman numeral, just two one's added together. Twelve is

LeetCode第[14]题(Java): Longest Common Prefix

题目:最长公共前缀 难度:EASY 题目内容: Write a function to find the longest common prefix string amongst an array of strings. If there is no common prefix, return an empty string "". 翻译:编写一个函数,在字符串数组中查找最长公共前缀字符串. 如果没有公共前缀,则返回空字符串. Example 1: Input: ["flow