内容简介:Cmn 非重复Cmn 重复的排序vector<vector<int>> subsetsWithDup(vector<int>& nums) {
排列
找下一个 https://leetcode.com/problems/next-permutation
void nextPermutation(vector<int>& nums) {
if(nums.size()<2){
return;
}
int i,j;
for(i=nums.size()-2;i>=0;i--){
if(nums[i]<nums[i+1]){ //1.找最后一个左边比右边小的begin
sort(nums.begin()+i+1,nums.end()); //2.后面的升序排
for(j=i+1;j<nums.size();j++){
if(nums[j]>nums[i]){ //3.找比begin大的第一个数交换
swap(nums[i],nums[j]);
return;
}
}
break;
}
}
if(i<0){
sort(nums.begin(),nums.end());
return;
}
}
Anm
https://leetcode.com/problems/permutations-ii/
vector<vector<int>> permuteUnique(vector<int>& nums) {
vector<vector<int>> ret;
if(nums.empty()){
return ret;
}
sort(nums.begin(),nums.end()); //1.排序 每次第一个都会入,如果不 排序 跳过重复会用不了
permuteInner(nums,0,ret);
return ret;
}
void permuteInner(vector<int> nums,int stable,vector<vector<int>>& ret) {
if(stable==nums.size()-1){
ret.push_back(nums);
return;
}
for(int j=stable;j<nums.size();j++){
//2.跳过重复
if(stable!=j&&nums[j]==nums[stable]){
continue;
}
//3.相当于前面j位已经排好,求j后面的排序组合,但前面j位可以是后面的任何一个。交换
swap(nums[stable],nums[j]);
permuteInner(nums,stable+1,ret);
}
}
Cmn 非重复
vector<vector<int>> subsets(vector<int>& nums) {
vector<vector<int>> ret{{}};
ret.push_back(tmp);
for(int i=0;i<nums.size();i++){
subsetsInner(nums[i], ret);
}
return ret;
}
void subsetsInner(int num,vector<vector<int>>& ret){
int len=ret.size();
for(int i=0;i<len;i++){
vector<int> tmp=ret[i];
tmp.push_back(num);
ret.push_back(tmp);
}
}
Cmn 重复的排序
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
sort(nums.begin(),nums.end());
vector<vector<int>> ret{{}};
for(int i=0;i<nums.size();i++){
vector<int> tmp(1,nums[i]);
while(i<nums.size()-1&&nums[i+1]==nums[i]){
i++;
tmp.push_back(nums[i]);
}
subsetsWithDup2(tmp,ret);
}
return ret;
}
void subsetsWithDup2(vector<int>& nums,vector<vector<int>>& ret){
int len=ret.size();
for(int i=0;i<len;i++){
for(int j=1;j<=nums.size();j++){
vector<int> tmp=ret[i];
tmp.insert(tmp.end(),nums.begin(),nums.begin()+j);
ret.push_back(tmp);
}
}
}
可重复和
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
vector<vector<int>> ret;
vector<int> sret;
sort(candidates.begin(),candidates.end());
combinationSumInner(candidates,0,target,sret,ret);
return ret;
}
void combinationSumInner(vector<int>& candidates,int begin,int target,vector<int>& sret,vector<vector<int>>& ret){
for(int i=begin;i<candidates.size();i++){
if(target-candidates[i]>0){
sret.push_back(candidates[i]);
combinationSumInner(candidates,i,target-candidates[i],sret,ret);
sret.erase(sret.end()-1);
}else if(target-candidates[i]==0){
sret.push_back(candidates[i]);
ret.push_back(sret);
sret.erase(sret.end()-1);
}
}
}
不可重复和
void combinationSumInner(vector<int>& candidates,int begin,int target,vector<int>& sret,vector<vector<int>>& ret){
for(int i=begin;i<candidates.size();i++){
if(i>begin && candidates[i]==candidates[i-1]) continue; //去重复
if(target-candidates[i]>0&&(i<candidates.size()-1)){
sret.push_back(candidates[i]);
combinationSumInner(candidates,i+1,target-candidates[i],sret,ret); //前移
sret.erase(sret.end()-1);
}else if(target-candidates[i]==0){
sret.push_back(candidates[i]);
ret.push_back(sret);
sret.erase(sret.end()-1);
}
}
}
数字加和
void combinationSumInner(int k,int begin,int n,vector<int>& sret,vector<vector<int>>& ret){
for(int i=begin;i<10;i++){
if(n-i>0&&(i<9)&&k>1){
sret.push_back(i);
combinationSumInner(k-1,i+1,n-i,sret,ret); //前移
sret.erase(sret.end()-1);
}else if(n-i==0&&k==1){
sret.push_back(i);
ret.push_back(sret);
sret.erase(sret.end()-1);
}
}
}
k-sum问题
转为一个和和k-1sum的问题。常规复杂度n^(k-1)
2-sum 首尾指针。或者一个hash 另一个查加和
3-sum 一个for 两个首尾。只要后面的
4-sum 2个先缓存,再用2-sum的chahe
链表
链表深拷贝
next和random两个不同指针的拷贝
//把2插入到1中,
//l1->next->random = l1->random->next
RandomListNode *copyRandomList(RandomListNode *head) {
RandomListNode *newHead, *l1, *l2;
if (head == NULL) return NULL;
for (l1 = head; l1 != NULL; l1 = l1->next->next) {
l2 = new RandomListNode(l1->label);
l2->next = l1->next;
l1->next = l2;
}
newHead = head->next;
for (l1 = head; l1 != NULL; l1 = l1->next->next) {
if (l1->random != NULL) l1->next->random = l1->random->next;
}
for (l1 = head; l1 != NULL; l1 = l1->next) {
l2 = l1->next;
l1->next = l2->next;
if (l2->next != NULL) l2->next = l2->next->next;
}
return newHead;
}
//用map把新旧映射后,random对应下
public RandomListNode copyRandomList(RandomListNode head) {
if (head == null) return head;
RandomListNode newHead = new RandomListNode(head.label);
RandomListNode oldp = head.next;
RandomListNode newp = newHead;
Map<RandomListNode, RandomListNode> map = new HashMap<RandomListNode, RandomListNode>();
//采用map结构来存储对应的关系
map.put(newp, head);
while (oldp != null) {//复制旧的链表
RandomListNode newTemp = new RandomListNode(oldp.label);
map.put(newTemp, oldp);
newp.next = newTemp;
newp=newp.next;
oldp=oldp.next;
}
oldp=head;
newp=newHead;
while (newp!=null){//复制random指针
newp.random=map.get(newp).random;//取得旧节点的random指针
newp=newp.next;
oldp=oldp.next;
}
return head;
}
链表翻转
ListNode* reverseList(ListNode* head) {
ListNode* cur = NULL;
while (head) {
ListNode* next = head -> next;
head -> next = cur;
cur = head;
head = next;
}
return cur;
}
ListNode* reverseList(ListNode* head) {
if (!head || !(head -> next)) {
return head;
}
ListNode* node = reverseList(head -> next);
head -> next -> next = head;
head -> next = NULL;
return node;
}
链表去重。要用删除后面节点。head不需要处理
字符串
窗口 https://blog.csdn.net/whdAlive/article/details/81132383
图
dijkstras
sptSet
邻接表 距离值 0和最大
a) 选择sptSet中不存在的顶点u并具有最小距离值。
b)包括u到sptSet。
c)更新u的所有相邻顶点的距离值。要更新距离值,请遍历所有相邻顶点。对于每个相邻顶点v,如果u(来自源)和边缘uv的权重的距离值之和小于v的距离值,则更新v的距离值。
#include <stdio.h>
#include <limits.h>
// Number of vertices in the graph
#define V 9
int minDistance(int dist[], bool sptSet[])
{
// Initialize min value
int min = INT_MAX, min_index;
for (int v = 0; v < V; v++)
if (sptSet[v] == false && dist[v] <= min)
min = dist[v], min_index = v;
return min_index;
}
int printSolution(int dist[], int n)
{
printf("Vertex Distance from Source\n");
for (int i = 0; i < V; i++)
printf("%d tt %d\n", i, dist[i]);
}
void dijkstra(int graph[V][V], int src)
{
int dist[V];
bool sptSet[V];
for (int i = 0; i < V; i++)
dist[i] = INT_MAX, sptSet[i] = false;
dist[src] = 0;
// Find shortest path for all vertices
for (int count = 0; count < V-1; count++)
{
int u = minDistance(dist, sptSet);
sptSet[u] = true;
for (int v = 0; v < V; v++)
if (!sptSet[v] && graph[u][v] && dist[u] != INT_MAX
&& dist[u]+graph[u][v] < dist[v])
dist[v] = dist[u] + graph[u][v];
}
// print the constructed distance array
printSolution(dist, V);
} // driver program to test above function
int main()
{
/* Let us create the example graph discussed above */
int graph[V][V] = {{0, 4, 0, 0, 0, 0, 0, 8, 0},
{4, 0, 8, 0, 0, 0, 0, 11, 0},
{0, 8, 0, 7, 0, 4, 0, 0, 2},
{0, 0, 7, 0, 9, 14, 0, 0, 0},
{0, 0, 0, 9, 0, 10, 0, 0, 0},
{0, 0, 4, 14, 10, 0, 2, 0, 0},
{0, 0, 0, 0, 0, 2, 0, 1, 6},
{8, 11, 0, 0, 0, 0, 1, 0, 7},
{0, 0, 2, 0, 0, 0, 6, 7, 0}
};
dijkstra(graph, 0);
return 0;
}
Floyd
多源最短路径
最开始只允许经过 1 号顶点进行中转,接下来只允许经过 1 和 2 号顶点进行中转。
#include <bits/stdc++.h>
using namespace std;
#define V 4
#define INF 99999
void printSolution(int dist[][V]);
void floydWarshall (int graph[][V])
{
int dist[V][V], i, j, k;
for (i = 0; i < V; i++)
for (j = 0; j < V; j++)
dist[i][j] = graph[i][j];
for (k = 0; k < V; k++)
{
// Pick all vertices as source one by one
for (i = 0; i < V; i++)
{
// Pick all vertices as destination for the
// above picked source
for (j = 0; j < V; j++)
{
if (dist[i][k] + dist[k][j] < dist[i][j])
dist[i][j] = dist[i][k] + dist[k][j];
}
}
}
// Print the shortest distance matrix
printSolution(dist);
}
/* A utility function to print solution */
void printSolution(int dist[][V])
{
cout<<"The following matrix shows the shortest distances"
" between every pair of vertices \n";
for (int i = 0; i < V; i++)
{
for (int j = 0; j < V; j++)
{
if (dist[i][j] == INF)
cout<<"INF"<<" ";
else
cout<<dist[i][j]<<" ";
}
cout<<endl;
}
}
// Driver code
int main()
{
int graph[V][V] = { {0, 5, INF, 10},
{INF, 0, 3, INF},
{INF, INF, 0, 1},
{INF, INF, INF, 0}
};
// Print the solution
floydWarshall(graph);
return 0;
}
DFS
void Graph::addEdge(int v, int w)
{
adj[v].push_back(w); // Add w to v’s list.
}
void Graph::DFSUtil(int v, bool visited[])
{
// Mark the current node as visited and
// print it
visited[v] = true;
cout << v << " ";
// Recur for all the vertices adjacent
// to this vertex
list<int>::iterator i;
for (i = adj[v].begin(); i != adj[v].end(); ++i)
if (!visited[*i])
DFSUtil(*i, visited);
}
// DFS traversal of the vertices reachable from v.
// It uses recursive DFSUtil()
void Graph::DFS(int v)
{
// Mark all the vertices as not visited
bool *visited = new bool[V];
for (int i = 0; i < V; i++)
visited[i] = false;
// Call the recursive helper function
// to print DFS traversal
DFSUtil(v, visited);
} void Graph::addEdge(int v, int w)
{
adj[v].push_back(w); // Add w to v’s list.
}
void Graph::DFSUtil(int v, bool visited[])
{
// Mark the current node as visited and
// print it
visited[v] = true;
cout << v << " ";
// Recur for all the vertices adjacent
// to this vertex
list<int>::iterator i;
for (i = adj[v].begin(); i != adj[v].end(); ++i)
if (!visited[*i])
DFSUtil(*i, visited);
}
// DFS traversal of the vertices reachable from v.
// It uses recursive DFSUtil()
void Graph::DFS(int v)
{
// Mark all the vertices as not visited
bool *visited = new bool[V];
for (int i = 0; i < V; i++)
visited[i] = false;
// Call the recursive helper function
// to print DFS traversal
DFSUtil(v, visited);
}
应用
word search
class GFG {
// Let the given dictionary be following
static final String dictionary[] = { "GEEKS", "FOR", "QUIZ", "GUQ", "EE" };
static final int n = dictionary.length;
static final int M = 3, N = 3;
static boolean isWord(String str)
{
// Linearly search all words
for (int i = 0; i < n; i++)
if (str.equals(dictionary[i]))
return true;
return false;
}
// A recursive function to print all words present on boggle
static void findWordsUtil(char boggle[][], boolean visited[][], int i,
int j, String str)
{
visited[i][j] = true;
str = str + boggle[i][j];
// If str is present in dictionary, then print it
if (isWord(str))
System.out.println(str);
// Traverse 8 adjacent cells of boggle[i][j]
for (int row = i - 1; row <= i + 1 && row < M; row++)
for (int col = j - 1; col <= j + 1 && col < N; col++)
if (row >= 0 && col >= 0 && !visited[row][col])
findWordsUtil(boggle, visited, row, col, str);
str = "" + str.charAt(str.length() - 1);
visited[i][j] = false;
}
// Prints all words present in dictionary.
static void findWords(char boggle[][])
{
// Mark all characters as not visited
boolean visited[][] = new boolean[M][N];
// Initialize current string
String str = "";
// Consider every character and look for all words
// starting with this character
for (int i = 0; i < M; i++)
for (int j = 0; j < N; j++)
findWordsUtil(boggle, visited, i, j, str);
}
}
BFS
void Graph::BFS(int s)
{
bool *visited = new bool[V];
for(int i = 0; i < V; i++)
visited[i] = false;
list<int> queue;
visited[s] = true;
queue.push_back(s);
list<int>::iterator i;
while(!queue.empty())
{
s = queue.front();
cout << s << " ";
queue.pop_front();
for (i = adj[s].begin(); i != adj[s].end(); ++i)
{
if (!visited[*i])
{
visited[*i] = true;
queue.push_back(*i);
}
}
}
}
拓扑排序
修改 DFS以查找图的拓扑排序。在 DFS中,我们从顶点开始,首先打印它,然后递归调用DFS作为其相邻顶点。在拓扑排序中,我们使用临时堆栈。我们不立即打印顶点,我们首先递归调用其所有相邻顶点的拓扑排序,然后将其推送到堆栈。最后,打印堆栈的内容。请注意,只有当顶点的所有相邻顶点(及其相邻顶点等)已经在堆栈中时,顶点才会被推送到堆栈。
void Graph::topologicalSortUtil(int v, bool visited[],
stack<int> &Stack)
{
// Mark the current node as visited.
visited[v] = true;
// Recur for all the vertices adjacent to this vertex
list<int>::iterator i;
for (i = adj[v].begin(); i != adj[v].end(); ++i)
if (!visited[*i])
topologicalSortUtil(*i, visited, Stack);
// Push current vertex to stack which stores result
Stack.push(v);
}
void Graph::topologicalSort()
{
stack<int> Stack;
// Mark all the vertices as not visited
bool *visited = new bool[V];
for (int i = 0; i < V; i++)
visited[i] = false;
// Call the recursive helper function to store Topological
// Sort starting from all vertices one by one
for (int i = 0; i < V; i++)
if (visited[i] == false)
topologicalSortUtil(i, visited, Stack);
// Print contents of stack
while (Stack.empty() == false)
{
cout << Stack.top() << " ";
Stack.pop();
}
}
最小生成树 primer:和最短路径差不多,每次找联通的定点 Kruskal:先找最小边各自连接 1.按重量的非递减顺序对所有边缘进行排序。 2.选择最小的边缘。检查它是否形成了到目前为止形成的生成树的循环。如果没有形成循环,则包括此边。否则,丢弃它。 3.重复步骤#2,直到生成树中有(V-1)条边。
还路判断
DFS + 是否在前面路径上(visited+rectrace)
bool Graph::isCyclicUtil(int v, bool visited[], bool *recStack)
{
if(visited[v] == false)
{
// Mark the current node as visited and part of recursion stack
visited[v] = true;
recStack[v] = true;
// Recur for all the vertices adjacent to this vertex
list<int>::iterator i;
for(i = adj[v].begin(); i != adj[v].end(); ++i)
{
if ( !visited[*i] && isCyclicUtil(*i, visited, recStack) )
return true;
else if (recStack[*i])
return true;
}
}
recStack[v] = false; // remove the vertex from recursion stack
return false;
}
bool Graph::isCyclic()
{
// Mark all the vertices as not visited and not part of recursion
// stack
bool *visited = new bool[V];
bool *recStack = new bool[V];
for(int i = 0; i < V; i++)
{
visited[i] = false;
recStack[i] = false;
}
// Call the recursive helper function to detect cycle in different
// DFS trees
for(int i = 0; i < V; i++)
if (isCyclicUtil(i, visited, recStack))
return true;
return false;
}
另一种:不相交集
int find(int parent[], int i)
{
if (parent[i] == -1)
return i;
return find(parent, parent[i]);
}
// A utility function to do union of two subsets
void Union(int parent[], int x, int y)
{
int xset = find(parent, x);
int yset = find(parent, y);
if(xset != yset)
{
parent[xset] = yset;
}
}
int isCycle( Graph* graph )
{
// Allocate memory for creating V subsets
int *parent = new int[graph->V * sizeof(int)];
// Initialize all subsets as single element sets
memset(parent, -1, sizeof(int) * graph->V);
// Iterate through all edges of graph, find subset of both
// vertices of every edge, if both subsets are same, then
// there is cycle in graph.
for(int i = 0; i < graph->E; ++i)
{
int x = find(parent, graph->edge[i].src);
int y = find(parent, graph->edge[i].dest);
if (x == y)
return 1;
Union(parent, x, y);
}
return 0;
}
割点和桥
割点:low[v] >= dnf[u]
桥:low[v] > dnf[u] 就说明V-U是桥
以上所述就是小编给大家介绍的《leetcode》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- LeetCode 题解,记录自己的 LeetCode 解题之路
- LeetCode 手记 16
- LeetCode:两数相加
- LeetCode (66):加一
- leetcode题解(动态规划)
- leetcode题解(动态规划)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
React Native:用JavaScript开发移动应用
【美】Truong Hoang Dung(张皇容) / 奇舞团 / 电子工业出版社 / 2015-9 / 65.00
React Native是当前移动端开发中的优秀解决方案。《React Native:用JavaScript开发移动应用》围绕着如何将一个完整App提交到App Store,讲解了使用React Native开发iOS应用所涉及的方方面面。首先介绍了Flexbox布局,教大家从零开始搭建一个初始应用,以此阐明React Native的基础运行机理;然后介绍了Flux的设计思想,怎么理解和使用Pro......一起来看看 《React Native:用JavaScript开发移动应用》 这本书的介绍吧!