目录
0 Lambda捕获
参考于:https://blog.csdn.net/xuruilin1993/article/details/117637721
static const auto io_sync_off = []()
{
std::ios::sync_with_stdio(false); // 取消cin,cout与stdio的同步
// untie in/out streams
std::cin.tie(nullptr); // 解除std::cin和std::cout之间的绑定,来降低IO的负担使效率提升
return nullptr;
}();
c++ std::cin 读入外部数据
c++ 向下兼容C,std :: cin、scanf一起出现 不出现错误 → C++用一个流缓冲区
同步C的标准流
std::ios::sync_with_stdio(false);
解除这种同步,std::cin 不再经过缓冲区 → 增加数据读取速度,减少代码执行时间
关闭同步后,程序中尽量不用c语言中的scanf,sscanf, getchar, fgets等函数,以免出现错误
找第k大的数
https://www.cnblogs.com/wangkundentisy/p/8810077.html
1
class Solution {
public:
/**
* @param x int整型
* @return int整型
*/
int sqrt(int x) {
// write code here
int l=1,m,h=x/2;
if(x<2)
return x;
else{
while(l<=h){
m = (l+h)/2;
if(x/m==m)
return m;
else if(x/m>m){
l = m+1;
}else{
h=m-1;
}
}
}
return h;
}
};
2
假设你有一个数组,其中第 i 个元素是股票在第 i 天的价格。
你有一次买入和卖出的机会。(只有买入了股票以后才能卖出)。请你设计一个算法来计算可以获得的最大收益
输入 [1,4,2]
输出 2
class Solution {
public:
/**
* @param prices int整型vector
* @return int整型
*/
int maxProfit(vector<int>& prices) {
// write code here
int res=0;
int len=prices.size();
int min_val=prices[0];
for(int i=0;i<len;++i){
if(prices[i]<min_val)min_val=prices[i];
res=max(res,prices[i]-min_val);
}
return res;
}
};
https://leetcode.cn/problems/binary-subarrays-with-sum/description/?languageTags=java
public class test3 {
public static void main(String[] args) {
int[] nums = new int[]{0,0,0,0,0};
int goal = 0;
int ans = numSubarraysWithSum(nums,goal);
System.out.println(ans);
}
public static int numSubarraysWithSum(int[] nums, int goal) {
int n = nums.length;
int[] sum = new int[n+1];
sum[0]=0;
for (int i = 1; i <= n; i++) {
sum[i] = sum[i-1]+nums[i-1];
}
Map<Integer,Integer> map = new HashMap<>();
map.put(0,1);
int l,r;
int ans = 0;
for (int i = 0; i < n; i++) {
r = sum[i+1];
l = r - goal;
ans += map.getOrDefault(l,0);
map.put(r,map.getOrDefault(r,0)+1);
}
return ans;
}
}
map.put(0,1);
该行不可或缺
原因:和为0 就相当于 sum[i] - goal = 0,i 就是我们要找的位置,就应该是1
3 多重链表合并
合并 k 个已排序的链表并将其作为一个已排序的链表返回
输入 [{1,2,3},{4,5,6,7}]
输出 {1,2,3,4,5,6,7}
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *mergeKLists(vector<ListNode *> &lists) {
ListNode *p = NULL;
int size = lists.size();
for(int i = 0; i < size; i++){
if(lists[i])
merge(p,lists[i]);
}
return p;
}
void merge(ListNode * &list1, ListNode * list2) {
ListNode *p;
if(list1 ==NULL)
list1 = list2;
else{
if(list1->val < list2->val){
p = list1;
list1 = list1->next;
}else{
p = list2;
list2 = list2->next;
}
ListNode *a = p;
while(list1!=NULL && list2!=NULL){
if(list1->val < list2->val){
p->next = list1;
list1 = list1->next;
}else{
p->next = list2;
list2 = list2->next;
}
p = p->next;
}
if(list1!=NULL)
p->next = list1;
else if(list2!=NULL)
p->next = list2;
list1 = a;
}
}
};
单链表排序
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
class Solution {
public:
/**
*
* @param head ListNode类 the head node
* @return ListNode类
*/
ListNode* sortInList(ListNode* head) {
// write code here
vector<int> temp;
ListNode* h = head;
while(h){
temp.push_back(h->val);
h = h->next;
}
sort(temp.begin(), temp.end());
h = head;
int size = temp.size(),i=0;
for(i = 0;i<size;i++){
h->val = temp[i];
h=h->next;
}
return head;
}
};
二维排序
题目
https://leetcode.cn/problems/reorder-data-in-log-files/description/?languageTags=java
class Node {
int id;
String log;
public Node(int id, String log) {
this.id = id;
this.log = log;
}
}
public class test0411 {
public static void main(String[] args) {
String[] logs = new String[]{"dig1 8 1 5 1","let1 art can","dig2 3 6","let2 own kit dig","let3 art zero"};
Stream.of(reorderLogFiles(logs)).forEach(System.out::println);
}
public static String[] reorderLogFiles(String[] logs) {
Node[] nodes = new Node[logs.length];
int length = logs.length;
for (int i = 0;i < length;i++){
nodes[i] = new Node(i,logs[i]);
}
Arrays.sort(nodes, (a,b)->compare(a,b));
String[] ans = new String[length];
for (int i = 0;i < length;i++){
ans[i] = nodes[i].log;
}
return ans;
}
private static int compare(Node a, Node b) {
String[] log1 = a.log.split(" ",2);
String[] log2 = b.log.split(" ",2);
boolean flag1 = Character.isDigit(log1[1].charAt(0));
boolean flag2 = Character.isDigit(log2[1].charAt(0));
if (flag1 && flag2){
return a.id - b.id;
}
if(!flag1 && !flag2){
int flag = log1[1].compareTo(log2[1]);
if(flag != 0)
return flag;
return log1[0].compareTo(log2[0]);
}
return flag1?1:-1;
}
}
贪心 滑动窗口
https://leetcode.cn/problems/maximum-white-tiles-covered-by-a-carpet/description/?orderBy=hot
public class test {
public static void main(String[] args) {
// int[][] tiles = new int[][]{{1, 5}, {10, 11}, {12, 18}, {20, 25}, {30, 32}};
// int[][] tiles = new int[][]{{10,11}, {1, 1}};
int[][] tiles = new int[][]{{1,1}, {4,6}};
int carpetLen = 4;
System.out.println(maximumWhiteTiles(tiles, carpetLen));
}
public static int maximumWhiteTiles(int[][] tiles, int carpetLen) {
Comparator cmp = new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
if (o1[0] == o2[0])
return o2[1] - o1[1];
return o1[0] - o2[0];
}
};
Arrays.sort(tiles, cmp);
int ans = 0;
int temp = 0;
int length = tiles.length;
for (int i = 0; i < length; i++) {
var j = i + 1;
while (j < length && (tiles[j][0] - tiles[i][0] < carpetLen)) {
j++;
}
int k = 0;
for (k = i; k < j - 1; k++) {
temp += (tiles[k][1] - tiles[k][0] + 1);
}
int t;
if (tiles[i][0] + carpetLen - 1 >= tiles[k][1])
t = tiles[k][1] - tiles[k][0] + 1;
else
t = tiles[i][0] + carpetLen - tiles[k][0];
temp = temp + t;
ans = Math.max(temp, ans);
if (tiles[i][0] + carpetLen - 1 >= tiles[length-1][1])
break;
temp = 0;
}
return ans;
}
}
两链表相加
public class Solution {
/**
*
* @param head1 ListNode类
* @param head2 ListNode类
* @return ListNode类
*/
public ListNode addInList (ListNode head1, ListNode head2) {
// write code here
if(head1 == null)
return head2;
else if(head2 == null)
return head1;
ListNode t1 = head1, t2= head2;
int[] a1 = new int[10000000];
int[] a2 = new int[10000000];
int length1 = 0, length2 = 0;
int i = 0, j = 0;
while(t1!=null){
a1[length1] = t1.val;
length1++;
t1 = t1.next;
}
while(t2!=null){
a2[length2] = t2.val;
length2++;
t2 = t2.next;
}
length1--;length2--;
int[] a3 = new int[10000000];
int length3 = 0;
int f = 0;
for(i = length1, j = length2;i >=0 && j >= 0;i--,j--,length3++){
a3[length3] = (a1[i] + a2[j] +f) %10;
f = (a1[i] + a2[j] + f)/10;
}
if(i >= 0){
while(i>=0){
a3[length3] = (a1[i] +f) %10;
f = (a1[i] + f)/10;
i--;
length3++;
}
}else if(j >= 0){
while(j>=0){
a3[length3] = (a2[j] +f) %10;
f = (a2[j] + f)/10;
j--;
length3++;
}
}
if(f > 0){
while(f>0){
a3[length3] = (f)%10;
f = (f)/10;
length3++;
}
}
ListNode ans = new ListNode(a3[length3-1]);
ListNode at = ans;
ListNode t = null;
for(i = length3-2;i >= 0; i--){
t = new ListNode(a3[i]);
at.next = t;
at = at.next;
}
System.out.println(length3);
return ans;
}
}
排列 next_permutation()
输入一个长度为n字符串,打印出该字符串中字符的所有排列
你可以以任意顺序返回这个字符串数组
例如输入字符串abc,则输出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
输入 “aab”
输出 [“aab”,“aba”,“baa”]
next_permutation()
会取得[first,last)所标示之序列的下一个排列组合
class Solution {
public:
vector<string> Permutation(string str) {
vector<string>ans;
if(str.size()==0)return ans;
//将str里的按字典序排序
sort(str.begin(),str.end());
do{
ans.push_back(str);
}while(next_permutation(str.begin(),str.end()));
return ans;
}
};
双指针
给定一个整形数组arr,已知其中所有的值都是非负的,将这个数组看作一个柱子高度图,计算按此排列的柱子,下雨之后能接多少雨水。
输入 [3,1,2,5,2,4]
返回 5
class Solution {
public:
/**
* max water
* @param arr int整型vector the array
* @return long长整型
*/
long long maxWater(vector<int>& arr) {
// write code here
if(arr.size() == 0)
return 0;
long long ans = 0L, left = 0, right = arr.size()-1, min1;
while(left < right){
min1 = min(arr[left],arr[right]);
while(left < right && arr[left] <= min1){
ans += (min1 - arr[left]);
left++;
}
while(left < right && arr[right] <= min1){
ans += (min1 - arr[right]);
right--;
}
}
return ans;
}
};
树 小偷
https://leetcode-cn.com/problems/house-robber-iii/solution/da-jia-jie-she-iii-by-leetcode-solution/
树 层次遍历
https://www.nowcoder.com/practice/c9480213597e45f4807880c763ddd5f0?tpId=117&tags=&title=&difficulty=0&judgeStatus=0&rp=0
根据二叉树的前序遍历,中序遍历恢复二叉树,并打印出二叉树的右视图
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
* 求二叉树的右视图
* @param xianxu int整型vector 先序遍历
* @param zhongxu int整型vector 中序遍历
* @return int整型vector
*/
struct tree{
int v;
tree* left;
tree* rigth;
tree(int v){
this->v = v;
this->left = this->rigth = NULL;
}
};
tree* re(vector<int>& xianxu, vector<int>& zhongxu, int l1, int r1,int l2, int r2){
if(l1>r1)
return NULL;
tree* root = new tree(xianxu[l1]);
for(int i = l2;i <=r2 ; i++){
if(zhongxu[i] == root->v){
root->left = re(xianxu, zhongxu, l1+1,l1+(i-l2),l2,i-1);
root->rigth = re(xianxu, zhongxu, l1+(i-l2)+1,r1,i+1,r2);
}
}
return root;
}
vector<int> solve(vector<int>& xianxu, vector<int>& zhongxu) {
// write code here
tree* root = re(xianxu, zhongxu, 0,xianxu.size()-1, 0, zhongxu.size()-1);
//tree* temp = new tree(0);
vector<int> ans;
if(root==nullptr){
return ans;
}
queue<tree*> que;
que.push(root);
int size, i;
while(!que.empty()){
size = que.size();
for(i = 0;i < size; i++){
root = que.front();
if(i == size - 1){
ans.push_back(root->v);
}
que.pop();
if(root->left){
que.push(root->left);
}
if(root->rigth){
que.push(root->rigth);
}
}
}
return ans;
}
};
树 求深度
/**
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
class Solution {
public:
/**
*
* @param root TreeNode类
* @return int整型
*/
int maxDepth(TreeNode* root) {
// write code here
if(root==nullptr)
return 0;
queue<TreeNode*> que;
que.push(root);
int size, i, ans = 0;
while(!que.empty()){
size = que.size();
for(i = 0; i < size; i++){
root = que.front();
que.pop();
if(root->left)
que.push(root->left);
if(root->right)
que.push(root->right);
}
ans++;
}
return ans;
}
};
平衡二叉树
断该二叉树是否是平衡二叉树
class Solution {
public:
bool ans = true;
bool IsBalanced_Solution(TreeNode* pRoot) {
dfs(pRoot);
return ans;
}
int dfs(TreeNode* root){
if(root==nullptr || ans==false)
return 0;
int dl = dfs(root->left);
int dr = dfs(root->right);
if(abs(dl-dr)>1)
ans = false;
return max(dl,dr)+1;
}
};
图 def
给一个01矩阵,1代表是陆地,0代表海洋, 如果两个1相邻,那么这两个1属于同一个岛。我们只考虑上下左右为相邻。
岛屿: 相邻陆地可以组成一个岛屿(相邻:上下左右) 判断岛屿个数。
输入
[
[1,1,0,0,0],
[0,1,0,1,1],
[0,0,0,1,1],
[0,0,0,0,0],
[0,0,1,1,1]
]
输出 3
class Solution {
public:
/**
* 判断岛屿数量
* @param grid char字符型vector<vector<>>
* @return int整型
*/
void def(vector<vector<char> >& grid, int x, int y){
if(x<0||x>=grid.size() || y <0 || y >=grid[0].size())
return;
if(grid[x][y] == '1'){
grid[x][y]= '0';
def(grid,x+1,y);
def(grid,x-1,y);
def(grid,x,y+1);
def(grid,x,y-1);
}
else if(grid[x][y] != '1')
return;
}
int solve(vector<vector<char> >& grid) {
// write code here
int ans = 0;
int i,j;
for(i = 0; i < grid.size(); i++){
for(j = 0; j<grid[0].size(); j++){
if(grid[i][j]=='1'){
def(grid,i,j);
ans++;
}
}
}
return ans;
}
};
矩阵最小路径和
给定一个 n * m 的矩阵 a,从左上角开始每次只能向右或者向下走,最后到达右下角的位置,路径上所有的数字累加起来就是路径和,输出所有的路径中最小的路径和。
class Solution {
public:
/**
*
* @param matrix int整型vector<vector<>> the matrix
* @return int整型
*/
int minPathSum(vector<vector<int> >& matrix) {
// write code here
int i ,j;
for(i = 1; i < matrix[0].size(); i++)
matrix[0][i] = matrix[0][i]+matrix[0][i-1];
for(i = 1; i < matrix.size(); i++)
matrix[i][0] = matrix[i][0] + matrix[i-1][0];
for(i = 1; i < matrix.size(); i++){
for(j = 1; j < matrix[0].size(); j++){
matrix[i][j] = matrix[i][j] + min(matrix[i-1][j],matrix[i][j-1]);
}
}
return matrix[i-1][j-1];
}
};
回文串 reverse
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* @param str string字符串 待判断的字符串
* @return bool布尔型
*/
bool judge(string str) {
// write code here
string str1 = str;
reverse(str.begin(),str.end());
if(str1 == str){
return true;
}else
return false;
}
};
找众数
https://www.nowcoder.com/practice/e8a1b01a2df14cb2b228b30ee6a92163?tpId=117&tags=&title=&difficulty=0&judgeStatus=0&rp=0
找出 数组中出现次数超过一半的数字
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
int ans = -1;
int i,n = 0;
for(i = 0; i < numbers.size(); i++){
if(numbers[i] == ans){
n++;
}else if((--n)<0){
ans = numbers[i];
n = 1;
}
}
return ans;
}
};
查找无重复最长子串
https://blog.csdn.net/qq_43669007/article/details/107567514
LRU缓存结构
import java.util.*;
public class Solution {
private Map<Integer, Node> map = new HashMap<>();
private Node head = new Node(-1,-1);
private Node tail = new Node(-1,-1);
private int k;
public int[] LRU (int[][] operators, int k) {
this.k = k;
head.next = tail;
tail.prev = head;
int len = (int)Arrays.stream(operators).filter(x -> x[0] == 2).count();
int[] res = new int[len];
for(int i = 0, j = 0; i < operators.length; i++) {
if(operators[i][0] == 1) {
set(operators[i][1], operators[i][2]);
} else {
res[j++] = get(operators[i][1]);
}
}
return res;
}
private void set(int key, int val) {
if(get(key) > -1) {
map.get(k).val = val;
} else {
if(map.size() == k) {
int rk = tail.prev.key;
tail.prev.prev.next = tail;
tail.prev = tail.prev.prev;
map.remove(rk);
}
Node node = new Node(key, val);
map.put(key, node);
moveToHead(node);
}
}
private int get(int key) {
if(map.containsKey(key)) {
Node node = map.get(key);
node.prev.next = node.next;
node.next.prev = node.prev;
moveToHead(node);
return node.val;
}
return -1;
}
private void moveToHead(Node node) {
node.next = head.next;
head.next.prev = node;
head.next = node;
node.prev = head;
}
static class Node{
int key, val;
Node prev, next;
public Node(int key, int val) {
this.key = key;
this.val = val;
}
}
}
从数组中找出其和为指定值的两个数
法一 暴力法
法二 散列表
https://blog.csdn.net/qq_42627977/article/details/109774858
public static int[] twoSum(int[] nums, int target) {
int[] ans = new int[2];
// 法一 暴力法
for(int i = 0; i < nums.length; i++){
for(int j = i + 1; j < nums.length; j++){
if( (nums[i] + nums[j]) == target ){
ans[0] = nums[i];
ans[1] = nums[j];
return ans;
}
}
}
return ans;
}
法三 双指针法
public static int[] twoSum(int[] nums, int target) {
int[] ans = new int[2];
// 法三 双指针法
Arrays.sort(nums);
int i = 0,j = 1;
while(i<j && j < nums.length){
if(nums[i] + nums[j] < target){
j++;
}else
i++;
while(nums[i] + nums[j] > target){
j--;
}
if(nums[i] + nums[j] == target){
break;
}
}
ans[0] = nums[i];
ans[1] = nums[j];
return ans;
}
任务调度
https://leetcode.cn/problems/task-scheduler/description/?orderBy=most_votes&languageTags=java
public int leastInterval(char[] tasks, int n) {
int[] buckets = new int[26];
for(int i = 0; i < tasks.length; i++){
buckets[tasks[i] - 'A']++;
}
Arrays.sort(buckets);
int maxTimes = buckets[25];
int maxCount = 1;
for(int i = 25; i >= 1; i--){
if(buckets[i] == buckets[i - 1])
maxCount++;
else
break;
}
int res = (maxTimes - 1) * (n + 1) + maxCount;
return Math.max(res, tasks.length);
}