1. Search in Rotated Sorted Array

Suppose an array sorted in ascending order is rotated(轮流,循环) at some pivot(枢轴; 中心点) unknown to you beforehand(提前; 事先).

(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).

You are given a target value to search. If found in the array return its index, otherwise return -1.

You may assume no duplicate exists in the array.

解析:这题要求是在一个数组中搜索目标数字,数组是经过升序排序后再按某一点旋转得来的,比如从 0 1 2 4 5 6 7  到 4 5 6 7 0 1 2。这个数组的特点是旋转轴的左边任何一个数字都比旋转轴右边数组中的数字要大,抓住这个特点利用改进的二分查找来解题。

public class Solution {
public int search(int[] A, int target) {
int lo = 0;
int hi = A.length - 1;
while (lo < hi) {
int mid = (lo + hi) / 2;
if (A[mid] == target) return mid;

// 这里判断数组 lo~mid 是不是旋转轴左边的一个升序部分,如果不是那么 mid~hi 构成右边的一个升序部分
if (A[lo] <= A[mid]) {
        // 如果target在这个左边升序部分那么在这个升序部分内继续二分查找,否则将lo置为mid后一位继续查找
if (target >= A[lo] && target < A[mid]) {
hi = mid - 1;
} else {
lo = mid + 1;
}
} else {
if (target > A[mid] && target <= A[hi]) {
lo = mid + 1;
} else {
hi = mid - 1;
}
}
}
return A[lo] == target ? lo : -1;
}
}

这题之所以要使用修改的二分查找是因为原数组再旋转后不是一个有序的数组了,就算 nums[mid]<target 也不能确定target再mid的左边还是右边,还要额外判断才行。

2. Search for a Range

Given an array of integers sorted in ascending order, find the starting and ending position of a given target value.

Your algorithm's runtime complexity must be in the order of O(log n).

If the target is not found in the array, return [-1, -1].

For example,
Given [5, 7, 7, 8, 8, 10] and target value 8,
return [3, 4].

解析:在一个升序数组中找一个数字出现的第一位置和最后一个位置,如果找不到则返回-1,难点在于如何再O(log n)内完成。使用线性扫描分别从左,右扫描找到第一个和最后一个,但是这样时间复杂度是O(n)。可以使用改进的二分查找来解决此题,当nums[mid]>=target时,target最左边的位置一定是在mid之前,或者是在mid上,而target最右边的位置一定出现再mid之后或者再mid上,所以将mid置为hi;如果nums[mid]<target,则表明target的最初出现位置在mid之后,继续二分查找。当lo>=hi时查找结束,此时如果 nums[mid]=target 则找到了最左(右)位置,否则返回-1。

下面的这个算法是首先利用二分查找找出第一个大于等于target的索引 start,如果start为数组长度length或者start位置的值不等于(也就是大于)target的话,则返回[-1, -1]。如果是等于则找到了第一个target出现的位置,再按次方法找target+1出现的第一个位置的索引,再减1即找到了最后一个target出现的位置。(注意此时target是确定存在的,所以 target+1 出现的位置一定是最后一个target出现的位置,当然有可能和第一个target的位置重合,即数组中target只出现了一次)

import java.util.*;

public class LeetCode{
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
String input=sc.nextLine().replaceAll("\\]|\\[| ",""); // 替换所有指定字符使用的是replaceAll方法,不是replace,谨记
int target=sc.nextInt();
String[] strs=input.split(",");
int[] A=new int[strs.length];
for(int i=0;i<strs.length;i++)
A[i]=Integer.parseInt(strs[i]); int[] res=new int[2];
int start=firstGreaterEqual(A, target);
if(start==A.length||A[start]!=target) // firstGreaterEqual方法第一次调用就可以判断出数组中存不存在target
res = new int[]{-1,-1};
else
res = new int[]{start, firstGreaterEqual(A, target+1)-1};
for(int a:res)
System.out.print(a+" ");
} static int firstGreaterEqual(int[] A, int target){
int low=0, high=A.length;
while(low<high){
int mid=low+((high-low)>>1);
      if(A[mid]<target){
low=mid+1;
}else{
high=mid;
}
}
return low;
}
}

3. Valide Sudoku

Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku board could be partially filled, where empty cells are filled with the character '.'.

解析:判断给定的数独是否合法,这题可以遍历二维数组来实现,行和列的判断不难,但是如何判断一个九宫格(3*3)内的数字是否不重复呢?难点在于根据行索引 i,和列索引 j 来对应九宫格内的索引,感觉是一道找规律的数学题额。

用第一行的索引构造第一个九宫格的索引,第二行的索引构造第二个九宫格的索引,以此类推。

public boolean isValidSudoku(char[][] board) {
for(int i = 0; i<9; i++){
HashSet<Character> rows = new HashSet<Character>();
HashSet<Character> columns = new HashSet<Character>();
HashSet<Character> cube = new HashSet<Character>();
for (int j = 0; j < 9;j++){
if(board[i][j]!='.' && !rows.add(board[i][j]))  //HashSet的add方法,如果元素不在集合中则添加成功,返回true
return false;
if(board[j][i]!='.' && !columns.add(board[j][i]))
return false;
/* 下面部分根据行索引i和列索引j来构造九宫格内的索引,比如在第一个循环中
* i是0,j是从0到9,由此来构造第一个九宫格内的索引:
      * [0,0],[0,1],[0,2]
* [1,0],[1,1],[1,2]
* [2,0],[2,1],[2,2]
     */
int RowIndex = 3*(i/3); //0~2为一组,行基准为0;3~5为一组,行基准为3;6~8为一组,行基准是6.
int ColIndex = 3*(i%3);    //第二行的索引对应第二个九宫格的索引,所以可以首先判断出行列基准都是和行号有关的
if(board[RowIndex + j/3][ColIndex + j%3]!='.' && !cube.add(board[RowIndex + j/3][ColIndex + j%3])) //在基准的基础上加相对应的值
return false;
}
}
return true;
}

这题说明了一个道理:就是再遍历矩阵的时候。除运算 / 和取余运算 % 是非常有用的。Discussion里也有网友详细说明了这点: https://leetcode.com/problems/valid-sudoku/discuss/15450

LeetCode解题报告—— Search in Rotated Sorted Array & Search for a Range & Valid Sudoku的更多相关文章

  1. 49. Search in Rotated Sorted Array && Search in Rotated Sorted Array II

    Search in Rotated Sorted Array Suppose a sorted array is rotated at some pivot unknown to you before ...

  2. Search in Sorted Array,Search in Rotated Sorted Array,Search in Rotated Sorted ArrayII

    一:Search in Sorted Array 二分查找,可有重复元素,返回target所在的位置,只需返回其中一个位置,代码中的查找范围为[low,high),左闭右开,否则容易照成死循环. 代码 ...

  3. [Leetcode] Search in Rotated Sorted Array 系列

    Search in Rotated Sorted Array 系列题解 题目来源: Search in Rotated Sorted Array Search in Rotated Sorted Ar ...

  4. LeetCode: Search in Rotated Sorted Array II 解题报告

    Search in Rotated Sorted Array II Follow up for "LeetCode: Search in Rotated Sorted Array 解题报告& ...

  5. LeetCode: Search in Rotated Sorted Array 解题报告

    Search in Rotated Sorted Array Suppose a sorted array is rotated at some pivot unknown to you before ...

  6. 【LeetCode】81. Search in Rotated Sorted Array II 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址:https://leetcode.com/problems/search-in ...

  7. [LeetCode] Search in Rotated Sorted Array I (33) && II (81) 解题思路

    33. Search in Rotated Sorted Array Suppose a sorted array is rotated at some pivot unknown to you be ...

  8. leetCode 33.Search in Rotated Sorted Array(排序旋转数组的查找) 解题思路和方法

    Search in Rotated Sorted Array Suppose a sorted array is rotated at some pivot unknown to you before ...

  9. leetCode 81.Search in Rotated Sorted Array II (旋转数组的搜索II) 解题思路和方法

    Follow up for "Search in Rotated Sorted Array": What if duplicates are allowed? Would this ...

随机推荐

  1. 20165218 2017-2018-1《Java程序设计》第二周学习总结

    20165218 2017-2018-1 <Java程序设计>第2周学习总结 教材学习内容总结 Ch2 基本数据类型与数组 Unicode字符集之中所有都叫做"字母", ...

  2. centos7下使用yum安装redis

    centos7下使用yum安装Redis 第一步:安装 yum –y install redis 第二步:启动 systemctl start redis.service 第三步:设置开机启动 sys ...

  3. 【Android】完善Android学习(四:API 3.1)

    备注:之前Android入门学习的书籍使用的是杨丰盛的<Android应用开发揭秘>,这本书是基于Android 2.2API的,目前Android已经到4.4了,更新了很多的API,也增 ...

  4. windows下codeblocks报错undefined reference to `WSAStartup@8'|

    Windows下C++Socket编程,调用WSAStartup函数报错:undefined reference to `WSAStartup@8'| 本人使用的是Codeblocks MinGW M ...

  5. PHP网页架站

    目前,Windows下已经有集成的PHP网页架站工具,例如:AppServ.WampServer.这些软件将Apache.PHP.MySQL.phpMyAdmin集成到一起,极大地方便了开发者架站.但 ...

  6. Item 2---遇到构造器具有多个参数时,要考虑用构建器;Builder模式

    问题,面对这种一个构造器具备多个参数的问题,现有的做法是使用重叠构造器的方式,该方式存在的问题: public class NutritionFacts { private final int ser ...

  7. 【Codeforces711E】ZS and The Birthday Paradox [数论]

    ZS and The Birthday Paradox Time Limit: 20 Sec  Memory Limit: 512 MB Description Input Output Sample ...

  8. Windows Server 2008 R2英文版修改桌面主题(Win7主题)

    1:首先打开Server Manager(凡是不知道在那里开发均可像Win7一样在运行里面搜索) 2:然后在左边的树形菜单中选择:Feature 点击右边页面中的:Add Features 这时候会出 ...

  9. vue手势解决方案

    1.需求 因为项目中要做一个可以移动.旋转和放缩具有合成图片的功能,例如: 剑可以随意移动,然后把位移.旋转角度和放缩值传给后台进行合成. 2.解决方案 网上搜到手势插件AlloyFinger,htt ...

  10. 概率DP入门学习QAQ

    emmmm博客很多都烂尾了...但是没空写..先写一下正在学的东西好了 概率DP这东西每次考到都不会..听题解也是一脸懵逼..所以决定学习一下这个东东..毕竟NOIP考过...比什么平衡树实在多了QA ...