/*给你两个按非递减顺序排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。
请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。
注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,
其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n 。*/package com.itkxw.BrushQuestions; import java.util.Arrays; /** * @Description: * @ClassName: Test01 * @Author: 康小汪 * @Date: 2023/11/9 21:35 * @Version: 1.0 */ /*给你两个按非递减顺序排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。 请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。 注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n, 其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n 。*/ public class Test01 { public static void main(String[] args) { int[] nums1 = {}; int[] nums2 = {}; int m = nums1.length - 3; int n = nums2.length; merge(nums1,m,nums2,n); } public static void merge(int[] nums1, int m, int[] nums2, int n) { for (int i = 0; i < n; i++) { nums1[m+i]=nums2[i]; } Arrays.sort(nums1); for (int i = 0; i < nums1.length; i++) { System.out.print(nums1[i]); } } }
给你一个数组
nums
和一个值val
,你需要 原地 移除所有数值等于val
的元素,并返回移除后数组的新长度。不要使用额外的数组空间,你必须仅使用
O(1)
额外空间并 原地 修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
因为元素的顺序可以改变。也不需要考虑数组中超出新长度后面的元素。
我们可以把输出的数组直接写到输入的数组上。
定义左右指针,右指针指向要处理的元素,如果当前元素是要处理的元素,左指针不动,右指针右移一位;如果当前元素不是要处理的元素,将右指针指向的元素赋值给左指针指向的元素,然后左右指针同时右移一位。
package com.itkxw.BrushQuestions;
/**
* @Description:
* @ClassName: Test02
* @Author: 康小汪
* @Date: 2023/11/10 11:12
* @Version: 1.0
*/
/*给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。*/
public class Test02 {
public static void main(String[] args) {
int[] nums = {0,1,2,2,3,0,4,2};//[1,2,2,3,4,2,4,2]
int val = 0;
int i = removeElement(nums, val);
System.out.println(i);
System.out.print("[");
for (int i1 = 0; i1 < nums.length; i1++) {
if (i1!=nums.length-1){
System.out.print(nums[i1]+",");
}else {
System.out.print(nums[i1]+"]");
}
}
}
public static int removeElement(int[] nums, int val) {
int left = 0;
for (int right = 0; right < nums.length; right++) {
if (nums[right]!=val){
nums[left] = nums[right];
left++;
}
}
return left;
}
}
让两个指针分别指向数组首位元素,从两边遍历数组,如果第一个元素是要处理的元素,直接用尾指针指向的元素替换它,然后尾指针往前移一位;否则左指针往后移一位。
package com.itkxw.BrushQuestions;
/**
* @Description:
* @ClassName: Test02
* @Author: 康小汪
* @Date: 2023/11/10 11:12
* @Version: 1.0
*/
/*给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。*/
public class Test02 {
public static void main(String[] args) {
int[] nums = {0,0,2,2,3,0,4,0};//[1,2,2,3,4,2,4,2]
int val = 0;
int i = removeElement(nums, val);
System.out.println(i);
System.out.print("[");
for (int i1 = 0; i1 < nums.length; i1++) {
if (i1!=nums.length-1){
System.out.print(nums[i1]+",");
}else {
System.out.print(nums[i1]+"]");
}
}
}
public static int removeElement(int[] nums, int val) {
int left = 0;
int right = nums.length;
while (left
如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。
字母和数字都属于字母数字字符。
给你一个字符串
s
,如果它是 回文串 ,返回true
;否则,返回false
。
先利用Character.isLetterOrDigit(c)判断字符是否为字母或数字,如果是,将它添加到StringBuffer中,然后用StringBuffer中的reverse()方法反转字符串
package com.itkxw.BrushQuestions;
/**
* @Description:
* @ClassName: Test03
* @Author: 康小汪
* @Date: 2023/11/10 18:08
* @Version: 1.0
*/
/*如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。
字母和数字都属于字母数字字符。
给你一个字符串 s,如果它是 回文串 ,返回 true ;否则,返回 false 。*/
public class Test03 {
public static void main(String[] args) {
String str = "race a car";
System.out.println(isPalindrome(str));
}
public static boolean isPalindrome(String s) {
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if(Character.isLetterOrDigit(c)){
stringBuffer.append(c);
}
}
String str = new StringBuffer(stringBuffer).toString().toLowerCase();
String string = stringBuffer.reverse().toString().toLowerCase();
if (str.equals(string)) {
return true;
}
return false;
}
}
给定一个字符串
s
,请你找出其中不含有重复字符的 最长子串 的长度。
滑动窗口+HashMap
左右两个指针,左指针指向字符串头部的前一个位置,右指针指向字符串第一个位置;判断hashmap中的key有没有这个元素,如果有,更新左指针,如果没有,更新右指针,更新结果
package com.itkxw.BrushQuestions;
import java.util.HashMap;
/**
* @Description:
* @ClassName: Test04
* @Author: 康小汪
* @Date: 2023/11/10 19:25
* @Version: 1.0
*/
//给定一个字符串,请你找出其中不含有重复字符的最长子串的长度。
public class Test04 {
public static void main(String[] args) {
String str = "abcabcfbb";
System.out.println(lengthOfLongestSubstring(str));
}
public static int lengthOfLongestSubstring(String s) {
HashMap hashMap = new HashMap<>();
int left = -1;
int count = 0;
int length = s.length();
for (int right = 0; right < length; right++){
if (hashMap.containsKey(s.charAt(right))){
left = Math.max(left,hashMap.get(s.charAt(right)));//更新左指针
}
hashMap.put(s.charAt(right),right);//添加到哈希表
count = Math.max(count,right-left);//更新结果
}
return count;
}
}
给定一个含有
n
个正整数的数组和一个正整数target
。找出该数组中满足其总和大于等于
target
的长度最小的 连续子数组[numsl, numsl+1, ..., numsr-1, numsr]
,并返回其长度。如果不存在符合条件的子数组,返回0
。
滑动窗口
public static int minSubArrayLen(int target, int[] nums) {
int left = 0;//左指针
int right = 0;//右指针
int minLength = 0;//最小长度
int temp = 0;//和
while (right=target){
if (right - left + 1 < minLength || minLength == 0) {
minLength = right - left + 1;//更新最优结果
}
temp = temp - nums[left];//滑动窗口,缩小窗口
left++;
}
right++;
}
return minLength;
}
给你一个字符串
s
,由若干单词组成,单词前后用一些空格字符隔开。返回字符串中 最后一个 单词的长度。单词 是指仅由字母组成、不包含任何空格字符的最大子字符串。
从String尾部遍历字符串,如果尾部有空格,先过滤掉空格
如果尾部没有空格,在遇到第一个空格时,空格后面的那个字符串就是字符串中最后一个最大字串
public static int lengthOfLastWord(String s) {
//从String尾部遍历字符串,如果尾部有空格,先过滤掉空格
//如果尾部没有空格,在遇到第一个空格时,空格后面的那个字符串就是字符串中最后一个最大字串
int index = s.length() - 1;
int lengthStr = 0;
while (s.charAt(index)==' '){
index--;
}
while (index>=0&&s.charAt(index)!=' '){
lengthStr++;
index--;
}
return lengthStr;
}
给你一个 非严格递增排列 的数组
nums
,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回nums
中唯一元素的个数。考虑
nums
的唯一元素的数量为k
,你需要做以下事情确保你的题解可以被通过:
- 更改数组
nums
,使nums
的前k
个元素包含唯一元素,并按照它们最初在nums
中出现的顺序排列。nums
的其余元素与nums
的大小不重要。- 返回
k
。
双指针
一个快指针,一个慢指针,因为数组是有序的,所以重复元素肯定相邻。让两个指针开始都指向1索引处的元素,比较快指针和它前一个位置的元素是否相等,相等的话就后移快指针,不相等的话,就把快指针位置的元素赋值给慢指针指向的位置,直到快指针到达数组末尾,然后返回慢指针的索引就是删除后数组的长度。
int len = nums.length;
int fast = 1;
int slow = 1;
if (len==0){
return 0;
}
while (fast
给你一个整数
x
,如果x
是一个回文整数,返回true
;否则,返回false
。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
- 例如,
121
是回文,而123
不是。
简单粗暴,看看就行
将整数转成字符串,比较字符串与它反转之后是否相等。
public static boolean isPalindrome(int x) {
StringBuilder stringBuilder = new StringBuilder(x+"");
String string = stringBuilder.reverse().toString();
return string.equals(x+"");
}
一个整数是否回文,只需拿到后半段的反转与前半段比较就行,比如1221,后半段 反转是12,等于前半段,他是回文数。
那么怎么取到后半段呢?假设整数为y
先取最低位:x=y%10
将取到的最低位加到取出数的末尾:z=z*10+x
每取一次最低位,整数都要除以10
public static boolean isPalindrome(int x) {
//如果是负数或者最后一位数是0,直接返回false
if (x < 0 || (x % 10 == 0 && x != 0)) {
return false;
}
int endX = 0;
//当前半段大于后半段时执行循环
while (x > endX) {
endX = endX * 10 + x % 10;
x = x / 10;
}
return (x==endX)||(x==endX/10);
}
给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。
最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。
你可以假设除了整数 0 之外,这个整数不会以零开头。
只关注末尾有没有9,假如末尾是9,比如:[1,2,3,9],我们只需要将3+1,将9置0即可;
没有9,比如[1,2,3],直接3+1就行;都是9,比如[9,9,9],这是我们就要将数组长度加1[1,0,0,0]。
public static int[] plusOne(int[] digits) {
int len = digits.length;
for (int i = len - 1; i >= 0; i--) {//逆序循环遍历数组
if (digits[i] != 9) {//这个元素不为9,就直接加1
digits[i]++;
//当前元素为9时,将当前元素后面的元素置为0
for (int j = i+1;j
给你一个有序数组
nums
,请你 原地 删除重复出现的元素,使得出现次数超过两次的元素只出现两次 ,返回删除后数组的新长度。不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
思路可以参考 第七题 ;
定义两个指针,遍历数组,找出应该保留的元素,将不应该保留的元素直接原地替换。
public static int removeDuplicates(int[] nums) {
int len = nums.length;
//重复元素只能出现两次,如果长度小于等于2,
//符合题目要求,直接返回数组长度
if (len<=2){
return len;
}
int fast = 2;
int slow = 2;
while (fast
给定一个大小为
n
的数组nums
,返回其中的多数元素。多数元素是指在数组中出现次数 大于⌊ n/2 ⌋
的元素。你可以假设数组是非空的,并且给定的数组总是存在多数元素
示例 1:
输入:nums = [3,2,3] 输出:3示例 2:
输入:nums = [2,2,1,1,1,2,2] 输出:2
使用哈希映射来存储每个元素以及出现的次数,对于hashmap中的每个键值对,键表示一个元素,值表示该元素出现的次数。
public static int majorityElement(int[] nums) {
HashMap hm = new HashMap<>();
//遍历数组,将数组中的元素作为hashmap的键
//重复元素将对应value的值加1
for (int num : nums) {
if (!hm.containsKey(num)){
hm.put(num,1);
}else {
hm.put(num, hm.get(num)+1);
}
}
int n = nums.length/2;
int a = 0;
for(Map.Entry entry: hm.entrySet()){
if (entry.getValue()>n){
a = entry.getKey();}
}
return a;
}
摩尔投票法就相当于候选人统计票数,遇到相同的,票数+1,遇到不同的票数-1,当票数为0的时候,会更换候选人,最终剩下的就是胜出者;
题目说,多数元素是指在数组中出现次数 大于
⌊ n/2 ⌋
的元素,那么超过一半的这个元素就相当于那个胜出的候选人。
// 摩尔投票法
//假设第一个元素是第一个候选人,他的票数设置为1
int candidate = nums[0];
int count = 1;
int len = nums.length;
for (int i = 0; i < len; i++) {
if (candidate == nums[i]){//如果下一票还是他,那么他的票数+1,否则-1
count++;
}else {
count--;
if (count==0){//当候选人的票数为0时,更换候选人,并且将票数置为1
candidate = nums[i];
count=1;
}
}
}
return candidate;
给定一个大小为 n 的整数数组,找出其中所有出现超过
⌊ n/3 ⌋
次的元素。
参考 第十一题 的思路 ,使用摩尔投票法。
给定一个整数数组
nums
,将数组中的元素向右轮转k
个位置,其中k
是非负数。
创建新数组,将元素按反转规则加入新数组,然后将新数组拷贝到原始数组。
public static void rotate(int[] nums, int k) {
// 1. 使用新数组解决问题
int len = nums.length;
int[] newArr = new int[len];
//数组翻转,放进新的数组里面
for (int i = 0; i < len; i++) {
newArr[(i + k) % len] = nums[i];
}
System.arraycopy(newArr, 0, nums, 0, len);
for (int i = 0; i < nums.length; i++) {
System.out.print(nums[i]);
}
}
我们可以将数组全部反转,这样需要翻转的数组就会跑到数组前面,然后按照需要翻转的个数将数组分成两部分,各自翻转就ok了。
k = 3
原数组 : 1,2,3,4,5,6,7
全部翻转 : 7,6,5,4,3,2,1
将数组分为 :7,6,5 和 4,3,2,1两个数组,进行各自翻转
结果 : 5,6,7,1,2,3,4
public static void rotate(int[] nums, int k) {
// 2. 翻转数组
int len = nums.length;
k %= len;
reverse(nums, 0, len - 1);
reverse(nums, 0, k - 1);
int[] reverse = reverse(nums, k, len - 1);
for (int i = 0; i < reverse.length; i++) {
System.out.print(reverse[i]);
}
}
public static int[] reverse(int[] nums, int start, int end) {
while (start < end) {
int temp = nums[start];
nums[start] = nums[end];
nums[end] = temp;
start++;
end--;
}
return nums;
}
给定一个数组
prices
,它的第i
个元素prices[i]
表示一支给定股票第i
天的价格。你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。
返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回
0
。
题目要求最大利润,就是找出股票最高点卖出,最低点买入。并且今天买只能以后卖。
从第一天开始找,找到最低点,如果不是最低点,继续找,如果是就找以后的最高点,计算出最高利润。
public static int maxProfit(int[] prices) {
int len = prices.length;
int max = 0;
int min = Integer.MAX_VALUE;
for (int i = 0; i < len; i++) {
if (prices[i]max) {
max = prices[i] - min;
}
}
return max;
}