38. Search a 2D Matrix II: 点击打开链接
[ [
1
,
3
,
5
,
7
], [
2
, 4, 7,
8
], [
3
, 5, 9,
10
] ]
思路:从第一行最后一个元素(或者第一列最后一个元素)开始遍历,记此元素为x
如果x<target,砍掉第一行
如果x>target,砍掉最后一列
如果x=target,count++,并同时砍掉第一行和最后一列
时间:O(m+n)
public class Solution {
/**
* @param matrix: A list of lists of integers
* @param: A number you want to search in the matrix
* @return: An integer indicate the occurrence of target in the given matrix
*/
public int searchMatrix(int[][] matrix, int target) {
if(matrix==null || matrix.length==0){
return 0;
}
int row=0;
int col=matrix[0].length-1;
int count=0;
while(row<=matrix.length-1 && col>=0){
if(target==matrix[row][col]){
count++;
row++;
col--;
}else if(target>matrix[row][col]){
row++;
}else{
col--;
}
}
return count;
}
}
161. Rotate Image: 点击打开链接
思路:顺时针90==两次翻转,同理可以推逆时针90
1 2 3
4 5 6
7 8 9
1 4
7
swap(matrix[i][j],matrix[j][i])
2 5 8
3
6 9
7
4
1
swap(matrix[i][j],matrix[i][matrix[0].length-1-j])
8 5 2 9 6 3
注意:do it in-place
public class Solution {
/**
* @param matrix: A list of lists of integers
* @return: Void
*/
public void rotate(int[][] matrix) {
for(int i = 0; i<matrix.length; i++){
for(int j = i; j<matrix[0].length; j++){
int temp = matrix[i][j];
matrix[i][j] = matrix[j][i];
matrix[j][i] = temp;
}
}
for(int i =0 ; i<matrix.length; i++){
for(int j = 0; j<matrix[0].length/2; j++){
int temp = matrix[i][j];
matrix[i][j] = matrix[i][matrix[0].length-1-j];
matrix[i][matrix[0].length-1-j] = temp;
}
}
}
}
654. Sparse Matrix Multiplication: 点击打开链接
|
1 0 0
| |
7
0 0 | |
7
0 0 |
7
=
1*7+0*0+0*0
AB = | -1 0 3 | x |
0
0 0 | = | -7 0 3 | |
0
0 1 |
思路:矩阵乘法:C[i][j]=A[i][k]*B[k][j] (如上例子,i=3,k=3,j=3)
时间:O(nmk)
方法一
public class Solution {
/**
* @param A a sparse matrix
* @param B a sparse matrix
* @return the result of A * B
*/
public int[][] multiply(int[][] A, int[][] B) {
int[][] result=new int[A.length][B[0].length];
for(int i=0;i<A.length;i++){
for(int j=0;j<B[0].length;j++){
for(int k=0;k<A[0].length;k++){
result[i][j]+=A[i][k]*B[k][j];
}
}
}
return result;
}
}
方法二
思路:由于是sparse,是稀疏矩阵,有好多0,因此要用上这一条件,但是怎么用时间上还是O(n^3)
public class Solution {
/**
* @param A a sparse matrix
* @param B a sparse matrix
* @return the result of A * B
*/
public int[][] multiply(int[][] A, int[][] B) {
int[][] result=new int[A.length][B[0].length];
for(int i=0;i<A.length;i++){
for(int k=0;k<A[0].length;k++){
if(A[i][k]==0){ //如果这边为0
continue;
}
for(int j=0;j<B[0].length;j++){
result[i][j]+=A[i][k]*B[k][j]; //这里的result也是0,因此A[i][k]=0时,continue
}
}
}
return result;
}
}
public class Solution {
/**
* @param A a sparse matrix
* @param B a sparse matrix
* @return the result of A * B
*/
public int[][] multiply(int[][] A, int[][] B) { //除了A[i][k]之外,B[k][j]也要取非零,又优化了一部分
int[][] result=new int[A.length][B[0].length];
for(int i=0;i<A.length;i++){
for(int k=0;k<A[0].length;k++){
if(A[i][k]!=0){
for(int j=0;j<B[0].length;j++){
if(B[k][j]!=0){
result[i][j]+=A[i][k]*B[k][j];
}
}
}
}
}
return result;
}
}
186. Max Points on a Line: 点击打开链接
思路:拿到当前点和下一点,先判断是不是相同点,如果是,duplicate++,看下一点的下一点与当前点的关系
如果不是相同点,判断是不是垂直线(垂直线无法这样算斜率),如果是,vertical++,
如果不是垂直线,再在map里进行统计
/**
* Definition for a point.
* class Point {
* int x;
* int y;
* Point() { x = 0; y = 0; }
* Point(int a, int b) { x = a; y = b; }
* }
*/
public class Solution {
/**
* @param points an array of point
* @return an integer
*/
public int maxPoints(Point[] points) {
if(points==null || points.length == 0) {
return 0;
}
if(points.length <= 2){
return points.length;
}
int maxVal = Integer.MIN_VALUE;
for(int i = 0; i < points.length-1; i++){
HashMap<Double, Integer> map = new HashMap<Double, Integer>();
int vertical=1;
int duplicate = 0;
int currMax = 0;
for(int j = i + 1; j < points.length; j++){ //for循环j里的每一点都要和当前点i比较
if(points[i].x == points[j].x && points[i].y == points[j].y){
duplicate++;
continue;
}
if(points[i].x == points[j].x){
vertical++;
continue;
}
double k=(double)(points[i].y-points[j].y)/(double)(points[i].x-points[j].x);
if(!map.containsKey(k)){
map.put(k,2);
}else{
map.put(k,map.get(k)+1);
}
currMax = Math.max(currMax, map.get(k)); //经过map统计,得到普通共线最大值
}
currMax = Math.max(vertical, currMax) + duplicate; //经过该点i的普通线和垂直线那种多,再加上该点的相同点
maxVal = Math.max(currMax, maxVal); //由于maxVal定义的位置,因此还得加上这句
}
return maxVal;
}
}
655. Big Integer Addition: 点击打开链接
public class Solution {
/**
* @param num1 a non-negative integers
* @param num2 a non-negative integers
* @return return sum of num1 and num2
*/
public String addStrings(String num1, String num2) {
int diff=Math.abs(num1.length()-num2.length());
if(num1.length()>num2.length()){ //先把长度短的前面用0补齐
for(int i=0;i<diff;i++){
num2="0"+num2;
}
}else{
for(int i=0;i<diff;i++){
num1="0"+num1;
}
}
String result=""; //然后"模十除十"
int carry=0;
for(int i=num1.length()-1;i>=0;i--){
int sum=carry+(num1.charAt(i)-'0')+(num2.charAt(i)-'0');
int digit=sum%10;
result+=digit;
carry=sum/10;
}
if(carry!=0){ //最后一位如果有carry,直接加到result串上
result+=carry;
}
return new StringBuffer(result).reverse().toString();
}
}
408. Add Binary: 点击打开链接
public class Solution {
/**
* @param a a number
* @param b a number
* @return the result
*/
public String addBinary(String a, String b) {
int diff=Math.abs(a.length()-b.length());
if(a.length()>b.length()){
for(int i=0;i<diff;i++){
b="0"+b;
}
}else{
for(int i=0;i<diff;i++){
a="0"+a;
}
}
String result="";
int carry=0; //和上题一样,只不过是二进制,"模二除二"
for(int i=a.length()-1;i>=0;i--){
int sum=carry+(a.charAt(i)-'0')+(b.charAt(i)-'0');
int digit=sum%2;
result+=digit;
carry=sum/2;
}
if(carry!=0){
result+=carry;
}
return new StringBuffer(result).reverse().toString();
}
}
167. Add Two Numbers: 点击打开链接
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
/**
* @param l1: the first list
* @param l2: the second list
* @return: the sum list of l1 and l2
*/
public ListNode addLists(ListNode l1, ListNode l2) {
if(l1==null && l2==null){
return null;
}
ListNode dummy=new ListNode(-1);
ListNode head=dummy;
int carry=0;
while(l1!=null && l2!=null){
int sum=carry+l1.val+l2.val;
head.next=new ListNode(sum%10);
carry=sum/10;
l1=l1.next;
l2=l2.next;
head=head.next;
}
while(l1!=null){
int sum=carry+l1.val;
head.next=new ListNode(sum%10);
carry=sum/10;
l1=l1.next;
head=head.next;
}
while(l2!=null){
int sum=carry+l2.val;
head.next=new ListNode(sum%10);
carry=sum/10;
l2=l2.next;
head=head.next;
}
if(carry!=0){
head.next=new ListNode(carry);
}
return dummy.next;
}
}
656. Big Integer Multiplication: 点击打开链接
思路:pos[i+j+1]+=product这个时候pos[i+j+1]位置上的数是实际的数字,很可能大于10
pos[k]=digit这个时候pos[k]位置上的数是最后要放的那一位数,一定小于10
public class Solution {
public String multiply(String num1, String num2) {
int[] pos=new int[num1.length()+num2.length()]; //最大长度是num1.length()+num2.length()
for(int i=num1.length()-1;i>=0;i--){
for(int j=num2.length()-1;j>=0;j--){
int product=(num1.charAt(i)-'0')*(num2.charAt(j)-'0');
pos[i+j+1]+=product; //以45和123为例
}
} //for循环结束int[] pos={0,4,13,22,15}
int carry=0;
StringBuffer sb=new StringBuffer();
for(int k=pos.length-1;k>=0;k--){
int digit=(pos[k]+carry)%10;
carry=(pos[k]+carry)/10;
pos[k]=digit;
sb.insert(0,digit); //每次都放到到索引0位置
}
while(sb.length()>0 && sb.charAt(0)=='0'){ //trim前导零,有两种情况:
sb.deleteCharAt(0); //第一位是0,没有用满最大长度
} //或者最终乘积为0,例如999*0,不能输出"000"
return sb.length()==0?"0":sb.toString();
}
}
428. Pow(x,n): 点击打开链接
思路:二分法
public class Solution {
/**
* @param x the base number
* @param n the power number
* @return the result
*/
public double myPow(double x, int n) {
if(n==0){
return 1;
}
if(n<0){
x=1/x;
n=-n;
}
double v=myPow(x,n/2);
if(n%2==0){ //用n%2的好处是结果只有0或是1两种情况
return v*v;
}else{
return v*v*x;
}
}
}
2019/05/31补充Bit Manipulation:
最近做OA有感,觉得Bit太好用, 真是活生生用O(n)就可以解决一些题。
转一讲解很详细Bit原理的帖子: https://www.jianshu.com/p/25ddeb1d9adf
338. Counting Bits
class Solution {
public int[] countBits(int num) {
int[] results = new int[num+1];
if(num ==0)
{
results[0] = 0;
}
for(int i=0; i<=num; i++)
{
int countOne=0;
int cur=i;
while(cur>0) // 没啥难度,知道十进制转化二进制原理,自然就解出来
{ // 但是按Leetcode的提交统计,performance相对于DP还是差一些
if(cur%2 == 1)
{
countOne++;
}
cur = cur/2;
}
results[i]= countOne;
}
return results;
}
}