剑指offer
记录自己做题的思路和题解,水平有限代码写的不好,在努力啦!欢迎交流
1.数组中重复的数字
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
解题思路:这道题思路挺多的
1.1简单思路
将数组中的数字排序,然后扫描排序后的数组,时间复杂度O(n*log(n)),代码没写
1.2哈希表
遍历数组,判断是否在哈希表中,不存在则加入哈希表,存在则输出,时间复杂度O(n),空间复杂度O(n)
代码如下(示例):
public static int findRepeatNumber(int[] nums) {
Set<Integer> org = new HashSet<>();
for(int n:nums){
if(org.contains(n)){
return n;
}
org.add(n);
}
return -1;
}
1.3 数组
新建大小相同的数组,遍历原数组,将i位置的num[i]存储到新数组newnum[num[i]]位置。图解
插入前判断该位置是否为0,因为数组初始化全部初始化为0,非0则返回该值。0位置需要特殊处理
代码如下(示例):
public static int findRepeatNumber(int[] nums) {
int[] cop = new int[nums.length];
int count = 0;//用来检验0位置的个数
for(int i = 0;i<nums.length;i++){
int temp = nums[i];
if(temp == 0){
count++;
if(count >1){
return 0;
}
}
if(cop[temp] == 0){
cop[temp] = temp;
}
else {
return temp;
}
}
return -1;
}
2.二维数组查找
在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
解题思路:
2.1朴素想法
选择target与数组右上角元素作比较,target大,划去一行;target小,划去一列,图解如下
代码如下(示例):
class Solution {
public boolean findNumberIn2DArray(int[][] matrix, int target) {
if(matrix == null || matrix.length == 0){
return false;
}
int row = matrix.length;
int col = matrix[0].length;
int now_row = 0;
int now_col = col-1;
while(now_col >= 0 && now_row < row){
if(target > matrix[now_row][now_col]){
//划掉一行
now_row++;
}
else if(target < matrix[now_row][now_col]){
//划掉一列
now_col--;
}
else {
return true;
}
}
return false;
}
}
3.替换空格
实现一个函数,把字符串 s 中的每个空格替换成"%20"。
解题思路:这道题不难,一种方法是通过StringBuilder处理,一种是直接利用replace库函数
题解1
public String replaceSpace(String s) {
StringBuilder str = new StringBuilder();
int len = s.length();
for(int i = 0;i<len;i++){
char c = s.charAt(i);
if(c == ' '){
str.append("%20");
}
else {
str.append(c);
}
}
return str.toString();
}
题解2
return s.replaceAll(" ","%20");
4.从尾到头打印链表
1.这题我的想法是:先反转链表再顺序打印。思路简单,但代码看着多"%20"。
2.也可以采用栈,从尾到头打印符合栈后进先出的原则"%20"。
题解1
/**
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public static int[] reversePrint(ListNode head) {
ListNode n1 = head;
int count = 0;
while(n1 != null){
count ++;
n1 = n1.next;
}
ListNode node = reverListNode(head);
int[] arr = new int[count];
for(int i = 0;i<count;i++){
arr[i] = node.val;
node = node.next;
}
return arr;
}
public static ListNode reverListNode(ListNode head){
ListNode curr = head;
ListNode pre = null,next = null;
while(curr != null){
next = curr.next;
curr.next = pre;
pre = curr;
curr = next;
}
return pre;
}
}