28 实现strstr
28. 实现 strStr() - 力扣(LeetCode) (leetcode-cn.com)
实现 strStr() 函数。
给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回 -1 。
说明:
当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。
对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与 C 语言的 strstr() 以及 Java 的 indexOf() 定义相符。
示例 1:
输入:haystack = “hello”, needle = “ll”
输出:2
示例 2:
输入:haystack = “aaaaa”, needle = “bba”
输出:-1
示例 3:
输入:haystack = “”, needle = “”
输出:0
KMP算法
public int strStr(String haystack, String needle) {
if (haystack == null || needle == null || haystack.length() < needle.length()) {
return -1;
}
if (needle.length() == 0) {
return 0;
}
char[] str1 = haystack.toCharArray();
char[] str2 = needle.toCharArray();
int x = 0;
int y = 0;
int[] next = getNextArray(str2);
while (x < str1.length && y < str2.length) {
if (str1[x] == str2[y]) {
x++;
y++;
} else if (next[y] == -1) {
x++;
} else {
y = next[y];
}
}
return y == str2.length ? x - y : -1;
}
public static int[] getNextArray(char[] str2) {
if (str2.length == 1) {
return new int[]{-1};
}
int[] next = new int[str2.length];
next[0] = -1;
next[1] = 0;
int index = 2;
int c = 0;
while (index < next.length) {
if (str2[index - 1] == str2[c]) {
next[index++] = ++c;
} else if (c > 0) {
c = next[c];
} else {
next[index++] = 0;
}
}
return next;
}
29 两数相除
29. 两数相除 - 力扣(LeetCode) (leetcode-cn.com)
给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。
返回被除数 dividend 除以除数 divisor 得到的商。
整数除法的结果应当截去(truncate)其小数部分,例如:truncate(8.345) = 8 以及 truncate(-2.7335) = -2
示例 1:
输入: dividend = 10, divisor = 3
输出: 3
解释: 10/3 = truncate(3.33333…) = truncate(3) = 3
示例 2:
输入: dividend = 7, divisor = -3
输出: -2
解释: 7/-3 = truncate(-2.33333…) = -2
考虑 被除数和除数 为最小值的时候
倍增
public int divide(int dividend, int divisor) {
if (dividend == Integer.MIN_VALUE && divisor == -1) {
return Integer.MAX_VALUE;
}
if (divisor == 1){//除数为1 的情况 直接返回被除数
return dividend;
}
//符号情况
int sign = (dividend < 0 && divisor < 0) ? 1 : ((dividend < 0 || divisor < 0) ? -1 : 1);
//转为 负数 计算
dividend = dividend > 0 ? -dividend : dividend;
divisor = divisor > 0 ? -divisor : divisor;
int res = 0;
while (dividend <= divisor) {//倍增
int x = divisor, count = 1;
while (dividend - x <= x) {
count += count;
x += x;
}
res += count;
dividend -= x;
}
return sign < 0 ? -res : res;
}
33 搜索旋转排序数组
33. 搜索旋转排序数组 - 力扣(LeetCode) (leetcode-cn.com)
整数数组 nums 按升序排列,数组中的值 互不相同 。
在传递给函数之前,nums 在预先未知的某个下标 k(0 <= k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k+1], …, nums[n-1], nums[0], nums[1], …, nums[k-1]](下标 从 0 开始 计数)。例如, [0,1,2,4,5,6,7] 在下标 3 处经旋转后可能变为 [4,5,6,7,0,1,2] 。
给你 旋转后 的数组 nums 和一个整数 target ,如果 nums 中存在这个目标值 target ,则返回它的下标,否则返回 -1 。
示例 1:
输入:nums = [4,5,6,7,0,1,2], target = 0
输出:4
示例 2:
输入:nums = [4,5,6,7,0,1,2], target = 3
输出:-1
示例 3:
输入:nums = [1], target = 0
输出:-1
二分查找 ,找到目标值在那一侧
public int search(int[] nums, int target) {
int L = 0;
int R = nums.length - 1;
while (L <= R) {
int M = (L + R) / 2;
if (nums[M] == target) {
return M;
}
if (nums[0] <= nums[M]) {
if (nums[0] <= target && target < nums[M]) {
R = M - 1;
} else {
L = M + 1;
}
} else {
if (nums[M] < target && target <= nums[nums.length - 1]) {
L = M + 1;
} else {
R = M - 1;
}
}
}
return -1;
}
34 在排序数组中查找元素的第一个和最后一个位置
34. 在排序数组中查找元素的第一个和最后一个位置 - 力扣(LeetCode) (leetcode-cn.com)
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target,返回 [-1, -1]。
进阶:
你可以设计并实现时间复杂度为 O(log n) 的算法解决此问题吗?
示例 1:
输入:nums = [5,7,7,8,8,10], target = 8
输出:[3,4]
示例 2:
输入:nums = [5,7,7,8,8,10], target = 6
输出:[-1,-1]
示例 3:
输入:nums = [], target = 0
输出:[-1,-1]
二分查找
public int[] searchRange(int[] nums, int target) {
int[] ans = {-1, -1};
if (nums == null || nums.length == 0) {
return ans;
}
ans[0] = searchFirst(nums, target);
ans[1] = searchLast(nums, target);
return ans;
}
public static int searchFirst(int[] arr, int num) {
int L = 0;
int R = arr.length - 1;
int ans = -1;
while (L <= R) {
int mid = L + ((R - L) >> 1);
if (arr[mid] < num) {
L = mid + 1;
} else if (arr[mid] > num) {
R = mid - 1;
} else {
ans = mid;
R = mid - 1;
}
}
return ans;
}
public static int searchLast(int[] arr, int num) {
int L = 0;
int R = arr.length - 1;
int ans = -1;
while (L <= R) {
int mid = L + ((R - L) >> 1);
if (arr[mid] < num) {
L = mid + 1;
} else if (arr[mid] > num) {
R = mid - 1;
} else {
ans = mid;
L = mid + 1;
}
}
return ans;
}