前言
刷题链接:
https://www.nowcoder.com/exam/oj/ta?page=2&tpId=13&type=265
1. 搜索算法
JZ53 数字在升序数组中出现的次数
思路:遍历数组,count记录k值出现次数,返回count
public class Solution {
public int GetNumberOfK(int [] array , int k) {
int count = 0;
for(int i = 0; i<array.length;i++){
if(array[i] == k){
count++;
}
}
return count;
}
}
JZ4 二维数组中的查找
思路:暴力遍历法,此时时间复杂度为O(n2)
public class Solution {
public boolean Find(int target, int [][] array) {
boolean flag = false;
for(int i=0;i<array.length;i++){
for(int j=0;j<array[i].length;j++){
if(array[i][j] == target){
flag = true;
}
}
}
return flag;
}
}
进阶:空间复杂度 O(1) ,时间复杂度 O(n+m)
思路:观察矩阵特性为 某元素左下大于上方,小于右方。
首先以左下角为起点,若是它小于目标元素,则往右移动去找大的,若是他大于目标元素,则往上移动去找小的。
public class Solution {
public boolean Find(int target, int [][] array) {
if(array.length==0 || array[0].length==0){
return false;
}
int j=0;
int i=array.length-1;
while(i>=0 && j<array[0].length){
if(target<array[i][j]){
i--;
}else if(target>array[i][j]){
j++;
}else{
return true;
}
}
return false;
}
}
JZ11 旋转数组的最小数字
- 暴力法
public class Solution {
public int minNumberInRotateArray(int [] array) {
int min = array[0];
for(int i=0;i<array.length;i++){
if(min>array[i]){
min = array[i];
}
}
return min;
}
}
- 二分法
public class Solution {
public int minNumberInRotateArray(int [] array) {
int i=0;
int j=array.length-1;
while(i<j){
int m = (i+j)/2;
if(array[m]>array[j]){
i = m+1;
}else if(array[m]<array[j]){
j = m;
}else{
j--;
}
}
return array[i];
}
}
JZ38 字符串的排列
思路:元素的全排列,使用递归与回溯
参考https://www.cnblogs.com/qiyuanc/p/QA_JZ38.html
import java.util.*;
public class Solution {
ArrayList<String> result = new ArrayList<String>();
Set<String> strSet = new HashSet<String>();
public ArrayList<String> Permutation(String str) {
Backtrack(str.toCharArray(),0,strSet);
result.addAll(strSet);
return result;
}
public void Backtrack(char[] chs,int cur,Set<String> strSet){
if(cur >= chs.length){
strSet.add(String.valueOf(chs));
return;
}
for(int i=cur;i<chs.length;i++){
swap(chs,i,cur);
Backtrack(chs,cur+1,strSet);
swap(chs,i,cur);
}
}
public void swap(char[] chs, int i, int j){
char temp = chs[j];
chs[j] = chs[i];
chs[i] = temp;
}
}
JZ44 数字序列中某一位的数字
思路:找到数字序列的规律
- 小于10的数字一位数,1~9,共9个数字,9位;= 911
- 小于100的数字两位数,10~99,共90个数字,180位; = 9102
- 小于1000的数字三位数,100~999,共900个数字,2700位; =91010*3
要想知道n为什么数字,首先要知道处于哪个区间(<10,10~100…),然后需要知道是哪个数字,最后得到是该数字的哪一位。 - 区间的计算根据规律需要dight+=1; start*=10;;sum=9startdigit;
- 需要知道是哪个数字:num = start + (n - 1)/digit; 存储为String类型
- 需要知道是哪一位: index = (n-1)%digit;
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param n int整型
* @return int整型
*/
public int findNthDigit (int n) {
// write code here
int digit = 1;
long start = 1;
long sum = 9;
while(n>sum){
n -= sum; //减去上一个区间的个数
start *= 10; //当前区间的起始数字
digit++;
sum = 9*start*digit; //该区间的总个数
}
String num = ""+(start + (n-1)/digit); //n在哪个数字上
int index = (n-1) % digit;//n在数字的哪一位上
return (int)(num.charAt(index)-(int)('0'));
}
}