-
根据左右指针计算中间位置 m,并比较 m 与 m+1 的值,如果 m 较大,则左侧存在峰值,r = m,如果 m + 1 较大,则右侧存在峰值,l = m + 1
-
Base on : https://leetcode-cn.com/problems/find-peak-element/solution/hua-jie-suan-fa-162-xun-zhao-feng-zhi-by-guanpengc/ 作者:guanpengchn
36. 有效的数独
class Solution {
public:
bool isValidSudoku(vector<vector>& board) {
// 遍历每一行每一列
for(int i = 0;i < 9;i++){
int x[9],y[9];
for(int i = 0;i < 9;i++) x[i] = 0,y[i] = 0;
for(int j = 0;j < 9;j++){
int idxx = board[i][j] - ‘0’,idxy = board[j][i] - ‘0’;
if(idxx >=0 && idxx <= 9){
if(!x[idxx-1]) x[idxx-1] = 1;
else return false;
}
if(idxy >= 0 && idxy <= 9){
if(!y[idxy-1]) y[idxy-1] = 1;
else return false;
}
}
}
// 遍历九个方格
int count = 9;
int countx=-3,county=0;
while(count–){
countx+=3;
if(countx == 9) countx = 0,county+=3;
int st[9];
for(int i = 0;i < 9;i++) st[i] = 0;
for(int i = 0+county;i < 3+county;i++){
// 输出三行
for(int j = 0+countx;j < 3+countx;j++){
int idx = (int)(board[i][j] - ‘0’);
if(idx >= 1 && idx <= 9) {
if(!st[idx-1]) st[idx-1] = 1;
else return false;
}
}
}
}
return true;
}
};
650. 只有两个键的键盘
class Solution {
// 判断是否为指数
public boolean isPrime(int x){
if(x <= 2) return false;
for(int i = 2;i <= x/i;i++){
if(x%i==0) return false;
}
return true;
}
public int minSteps(int n) {
// dp[i],i这个数,最小的操作数
int[] dp = new int[n+1];
for(int i = 0;i <=n;i++){
// 质数
if(isPrime(i)) dp[i] = i;
// 偶数
else if(i%2 == 0) dp[i] = dp[i/2] + 2;
// 奇数
else {
for(int j = i-1;j > 0;j–){
if(i % j == 0){
dp[i] = dp[j] + i/j;
break;
}
}
}
}
return dp[n];
}
}
我觉得这个思路其实就相当DP了
300. 最长递增子序列
class Solution {
public int lengthOfLIS(int[] nums) {
int n = nums.length,maxL = 0;
int[] dp = new int[n];
for(int i = 0;i < n;i++){
dp[i] = 1;
for(int j = 0;j < i;j++){
if(nums[i] > nums[j]){
if(dp[j] + 1 > dp[i]) dp[i] = dp[j]+1;
}
}
if(dp[i] > maxL) maxL = dp[i];
}
return maxL;
}
}
DP分析:
-
dp数组以及下表含义:
-
以nums[i]结尾的元素的最长递增子序列的长度
-
dp的边界考虑
-
每次遍历之前dp[i]初始化为1,当作一个数字作为上升子序列
-
dp的状态转移方程
-
dp[i] = max(dp[j]) + 1
-
因为dp[j]表示第i个元素之前的最长递增子序列的长度,那么直接将num[i]插入最后面还能构成递增子序列的话就能求出dp[i]
-
遍历顺序
-
j在i之前,dp[i]需要dp[j],从左往右
-
打印dp表
673. 最长递增子序列的个数
class Solution {
public int findNumberOfLIS(int[] nums) {
int n = nums.length,maxL = 0,ans = 0;
// 以nums[i]结尾的最长上升子序列的长度
int[] dp = new int[n];
// 以nums[i]结尾的最长上升子序列的个数
int[] cnt = new int[n];
// 遍历
for(int i = 0;i < n;i++){
dp[i] = 1;
cnt[i] = 1;
for(int j = 0;j < i;j++){
// 可以直接加在dp[j]之后
if(nums[i] > nums[j]){
if(dp[j] + 1 > dp[i]){
// 能构成一个比之前长的递增子序列
dp[i] = dp[j]+1;
cnt[i] = cnt[j];
// 构成的上升子序列和之前的上升子序列一样长
}else if(dp[j] + 1 == dp[i]) cnt[i] += cnt[j];
}
}
// 刷新最大长度
if(dp[i] > maxL){
maxL = dp[i];
ans = cnt[i];
}else if(dp[i] == maxL) ans += cnt[i];
}
return ans;
}
}
DP分析的方法和上面一题一样,这里多了个cnt[]数组
cnt[i]表示以nums[i]结尾的最长上升子序列的个数
58. 最后一个单词的长度
class Solution {
public int lengthOfLastWord(String s) {
int ans = 0;
boolean flag = true;
for(int i = s.length()-1;i >=0;i–){
if(s.charAt(i) == ’ ’ && flag) continue;
else {
flag = false;
if(s.charAt(i) == ’ ') break;
ans++;
}
}
return ans;
}
}
从后面往前面遍历,从第一个不是空格的字母到第一个空格
326. 3的幂
class Solution {
public boolean isPowerOfThree(int n) {
long x = 1;
while(x <= n){
if(x == n) return true;
x *= 3;
}
return false;
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CPNXY67D-1634459055741)(https://i.loli.net/2021/09/23/hFNZm4jPOUqs9MT.png)]
371. 两整数之和
class Solution {
public int getSum(int a, int b) {
int count = 1;
while(b != 0){
// a & b 可以得出所有需要进位的位
// << 1 将进位的位置移到需要进位的地方
int carry = (a&b) << 1;
// ^ 异或运算,无进位加法
a = a ^ b;
b = carry;
}
return a;
}
}
https://leetcode-cn.com/problems/sum-of-two-integers/solution/liang-zheng-shu-zhi-he-by-leetcode-solut-c1s3/
1436. 旅行终点站
双重遍历:如果cityB没有在cityA出现过
class Solution {
public String destCity(List<List> paths) {
int n = paths.size();
for(int i = 0;i < n;i ++ ){
List list1 = paths.get(i);
String second = list1.get(1);
boolean flag = true;
for(int j = 0;j < n;j++){
List list2 = paths.get(j);
String first = list2.get(0);
if(first.equals(second)){
flag = false;
break;
}
}
if(flag) return second;
}
return null;
}
}
哈希表:
class Solution {
public String destCity(List<List> paths) {
Set hashSet = new HashSet<>();
// 遍历cityA
for(List list : paths){
String cityA = list.get(0);
hashSet.add(cityA);
}
// 遍历cityB,如果cityB没有在cityA出现过,那就是终点
for(List list : paths){
String cityB = list.get(1);
if(!hashSet.contains(cityB)) return cityB;
}
return null;
}
}
405. 数字转换为十六进制数
进制转换-> 辗转相除法
class Solution {
public String toHex(int _num) {
if(_num == 0) return “0”;
Stack stack = new Stack<>();
String str = “0123456789abcdef”;
long num = _num;
if(num < 0) num = (long)(Math.pow(2, 32) + num);
int size = 0;
while(num > 0){
long k = num % 16;
stack.push(str.charAt((int)k));
num /= 16;
size++;
}
char[] ans = new char[size];
int idx = 0;
for(int i = 0;i < size;i++) ans[idx++] = stack.pop();
return new String(ans);
}
}
调用函数:
class Solution {
public String toHex(int num) {
return Integer.toHexString(num);
}
}
166. 分数到小数
class Solution {
public String fractionToDecimal(int numerator, int denominator) {
// 转成long,防止溢出
long a = numerator,b = denominator;
// 如果自身能被整除,直接返回
if(a % b == 0) return String.valueOf(a / b);
StringBuilder sb = new StringBuilder();
// 如果有一个是负数,先追加负号
if(a * b < 0) sb.append(‘-’);
// 都先变为正数
a = Math.abs(a);b = Math.abs(b);
// 计算小数点前的数,并将余数赋值给a
sb.append(String.valueOf(a/b) + “.”);
a %= b;
Map<Long,Integer> map = new HashMap<>();
while(a != 0){
// 记录当前的余数所在位置,并且继续模拟除法
map.put(a,sb.length());
// 后面加0
a*=10;
sb.append(a/b);
// 余数
a %= b;
// 如果当前余数之前出现过,则将 [出现位置 到 当前位置] 的部分抠出来(循环小数部分)
if(map.containsKey(a)){
int u = map.get(a);
return String.format(“%s(%s)”,sb.substring(0,u),sb.substring(u));
}
}
// 有限小数
return sb.toString();
}
}
思路来源:https://leetcode-cn.com/problems/fraction-to-recurring-decimal/solution/gong-shui-san-xie-mo-ni-shu-shi-ji-suan-kq8c4/
482. 密钥格式化
两个char数组
class Solution {
public String licenseKeyFormatting(String s, int k) {
int n = s.length();
char[] ch = new char[n];
int len = 0;
for(int i = 0;i < n;i++){
if(s.charAt(i) != ‘-’) ch[len++] = Character.toUpperCase(s.charAt(i));
}
int cout = 0;
if(len%k == 0)cout = len/k-1;
else cout = len/k;
if(len + cout == -1) cout = 0;
char[] ans = new char[len+cout];
int idx = len+cout-1,k2 = k;
for(int i = len-1;i >= 0;i–){
if(idx >= 0)ans[idx–] = ch[i];
k2–;
if(k2 == 0 && idx >= 0) {
ans[idx–] = ‘-’;
k2 = k;
}
}
return new String(ans);
}
}
StringBuilder
class Solution {
public String licenseKeyFormatting(String s, int k) {
StringBuilder sb = new StringBuilder();
// 从后往前
for(int i = s.length()-1,cnt = 0;i >=0 ;i–){
if(s.charAt(i) == ‘-’) continue;
// 计数器
if(cnt == k){
sb.append(‘-’);
cnt = 0;
}
sb.append(s.charAt(i));
cnt++;
}
return sb.reverse().toString().toUpperCase();
}
}
284. 顶端迭代器
// Java Iterator interface reference:
// https://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html
class PeekingIterator implements Iterator {
// 迭代器
private Iterator iterator;
private Integer nextElement;
public PeekingIterator(Iterator iterator) {
// initialize any member here.
this.iterator = iterator;
nextElement = iterator.next();
}
// Returns the next element in the iteration without advancing the iterator.
public Integer peek() {
return nextElement;
}
// hasNext() and next() should behave the same as in the Iterator interface.
// Override them if needed.
@Override
public Integer next() {
Integer ret = nextElement;
nextElement = iterator.hasNext() ? iterator.next() : null;
return ret;
}
@Override
public boolean hasNext() {
return nextElement != null;
}
}
414. 第三大的数
有序序列:
-
TreeSet里面就放最大的三个元素
-
每次都把当前元素加进来,有重复的TreeSet自动去重
-
当大于三个的时候,把最小的,就是第一个清除即可
class Solution {
public int thirdMax(int[] nums) {
TreeSet treeSet = new TreeSet<>();
for(int i = 0;i < nums.length;i++){
treeSet.add(nums[i]);
// 弹出最小的
if(treeSet.size() > 3) treeSet.remove(treeSet.first());
}
return treeSet.size() == 3 ? treeSet.first():treeSet.last();
}
}
三个变量
class Solution {
public int thirdMax(int[] nums) {
Integer a = null,b = null,c = null;
for(Integer num : nums){
// 最大的
if(a == null || num > a){
c = b;
b = a;
a = num;
// 第二大的,要保证此时的num小于a,不能等于a
}else if((b == null || num > b) && a > num){
c = b;
b = num;
// 保证b以及复制了,并且当前的null小于b
}else if(b != null &&(c == null || num > c) && b > num){
c = num;
}
}
return c == null ? a : c;
}
}
排序
class Solution {
public int thirdMax(int[] nums) {
// 排序
Arrays.sort(nums);
// 从大到小
revers(nums);
int differ = 1;
// 最大的
int ans = nums[0];
for(int i = 1;i < nums.length;i++){
if(nums[i] != nums[i-1]) differ++;
if(differ == 3){
ans = nums[i];
break;
}
}
return ans;
}
public void revers(int[] nums){
int l = 0,r = nums.length-1;
while(l < r){
int temp = nums[l];
nums[l] = nums[r];
nums[r] = temp;
l++;r–;
}
}
}
434. 字符串中的单词数
class Solution {
public int countSegments(String s) {
int ans = 0;
if(s.equals(“”)) return 0;
for(int i = 0;i < s.length()-1;i++){
if(s.charAt(i) != ’ ’ && s.charAt(i+1) == ’ ') ans++;
}
if(s.charAt(s.length()-1 ) != ’ ')return ans+1;
return ans;
}
}
187. 重复的DNA序列
class Solution {
public List findRepeatedDnaSequences(String s) {
int n = s.length();
List ans = new ArrayList<>();
Map<String,Integer> hashMap = new HashMap<>();
if(n < 10) return ans;
for(int i = 0;i <= n - 10;i++){
// 截取子串
String sub = s.substring(i,i+10);
hashMap.put(sub,hashMap.getOrDefault(sub,0)+1);
if(hashMap.get(sub) == 2) ans.add(sub);
}
return ans;
}
}
441. 排列硬币
class Solution {
public int arrangeCoins(int n) {
int i = 1,count = 0;
while(n > 0){
if(n >= i) count++;
n-=i;
i++;
}
return count;
}
}
class Solution {
public List fizzBuzz(int n) {
List ans = new ArrayList<>();
for(int i = 1;i <= n;i++){
if(i % 3 == 0 && i % 5 == 0) ans.add(“FizzBuzz”);
else if(i % 3 == 0) ans.add(“Fizz”);
else if(i % 5 == 0) ans.add(“Buzz”);
else ans.add(String.valueOf(i));
}
return ans;
}
}
剑指 Offer II 069. 山峰数组的顶部
遍历:
class Solution {
public int peakIndexInMountainArray(int[] arr) {
int ans = 0,max = arr[0];
for(int i = 0;i < arr.length;i++){
if(max < arr[i]) {
ans = i;
max = arr[i];
}
}
return ans;
}
}
二分:
class Solution {
public int peakIndexInMountainArray(int[] arr) {
int l = 0,r = arr.length-1;
while(l < r){
int mid = (l+r)/2;
if(arr[mid] > arr[mid+1]) r = mid;
else l = mid+1;
}
return l;
}
}
230. 二叉搜索树中第K小的元素
/**
- Definition for a binary tree node.
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
剑指 Offer II 069. 山峰数组的顶部
遍历:
class Solution {
public int peakIndexInMountainArray(int[] arr) {
int ans = 0,max = arr[0];
for(int i = 0;i < arr.length;i++){
if(max < arr[i]) {
ans = i;
max = arr[i];
}
}
return ans;
}
}
二分:
class Solution {
public int peakIndexInMountainArray(int[] arr) {
int l = 0,r = arr.length-1;
while(l < r){
int mid = (l+r)/2;
if(arr[mid] > arr[mid+1]) r = mid;
else l = mid+1;
}
return l;
}
}
230. 二叉搜索树中第K小的元素
/**
- Definition for a binary tree node.
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-H45PHhSS-1715796925453)]
[外链图片转存中…(img-zEPSn2Xt-1715796925454)]
[外链图片转存中…(img-Rs6J6BWD-1715796925454)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!