begin

克鲁斯卡尔算法

橙三吉。 提交于 2020-02-13 13:54:20
环境: Codeblocks 13.12 + GCC 4.7.1 基本思想 :(1)构造一个只含n个顶点,边集为空的子图。若将图中各个顶点看成一棵树的根节点,则它是一个含有n棵树的森林。(2)从网的边集 E 中选取一条权值最小的边, 若该条边的两个顶点分属不同的树,则将其加入子图 。也就是说,将这两个顶点分别所在的两棵树合成一棵树;反之,若该条边的两个顶点已落在同一棵树上,则不可取,而应该取下一条权值最小的边再试之(3)依次类推,直至森林中只有一棵树,也即子图中含有 n-1条边为止。 大白话 :(1)将图中的所有边都去掉。(2)将边按权值从小到大的顺序添加到图中, 保证添加的过程中不会形成环 (3)重复上一步直到连接所有顶点,此时就生成了最小生成树。这是一种贪心策略。 难点 :判断某条边<u, v>的加入是否会在已经选定的边集集合中形成环。 解决办法 :使用 并查集 ,分别找出两个顶点u, v所在树的根节点。若根节点相同,说明u, v在同一棵树中,则u, v连接起来会形成环;若根节点不同,则u, v不在一棵树中,连接起来不会形成环,而是将两棵树合并。 图解过程:原图如下 边集数组按权值顺序排列 边<1, 2>和<4, 5>在添加到图中的时候形成了环,所以不能将v1和v2,v4和v5连起来。 判断是否成环 int Find(int *parent, int f) { while (

CCF认证201509-3模板生成系统

北战南征 提交于 2020-02-12 02:37:24
整体思路为:读入模板时识别所有变量,两边各加两个大括号处理之后,赋值为空串存入unordered_map;读入变量的同时进行处理,两边各加两个大括号,对已存入的进行修改。之后用每个变量遍历模板,寻找并替换即可。 # include <iostream> # include <algorithm> # include <string> # include <cstdio> # include <cstring> # include <vector> # include <sstream> # include <map> # include <set> # include <unordered_map> using namespace std ; unordered_map < string , string > mp ; int main ( ) { int m , n ; string a [ 110 ] ; cin >> m >> n ; getchar ( ) ; for ( int i = 0 ; i < m ; ++ i ) { string temp ; getline ( cin , temp ) ; int begin = 0 , end = 0 ; while ( ( begin = temp . find ( "{{ " , begin ) ) != string

Longest Substring Without Repeating Characters

北战南征 提交于 2020-02-12 01:18:34
Given a string, find the length of the longest substring without repeating characters. For example, the longest substring without repeating letters for "abcabcbb" is "abc", which the length is 3. For "bbbbb" the longest substring is "b", with the length of 1. 思路:本题找出字符串中最长的 不包含相同的字符 的子字符串不包含相同的字符。可以使用hash表来解决这道题。主要思路就是使用两个头尾指针,尾指针不断往后搜索,当该字符在前面出现过了,记录字符的长度和最长结果,此时头指针不断往后搜索,同时记录的长度count要减一,直到头指针指向的字符与尾指针相同时结束搜索,同时头指针向后移动一位,记录访问过的字符,长度count加一。最后优化最长结果。 class Solution { public: int lengthOfLongestSubstring(string s) { int n=s.size(); if(n<=1) return n; int result=0; int count=0; int begin=0;

1006 Sign In and Sign Out (25分)

左心房为你撑大大i 提交于 2020-02-08 18:59:35
#include <stdio.h> #include<iostream> using namespace std; struct ID { char id_num[16]; int begin; int end; }; int main() { int m,H,M,S; struct ID unlock_id,lock_id,tmp_id; unlock_id.begin=99999; lock_id.end=-1; scanf("%d",&m); for(int i=0;i<m;i++) { scanf("%s",tmp_id.id_num); scanf("%d:%d:%d",&H,&M,&S); S=H*3600+M*60; tmp_id.begin=S; scanf("%d:%d:%d",&H,&M,&S); S=H*3600+M*60; tmp_id.end=S; if(tmp_id.begin<unlock_id.begin) unlock_id=tmp_id; if(tmp_id.end>lock_id.end) lock_id=tmp_id; } cout<<unlock_id.id_num<<" "<<lock_id.id_num<<endl; return 0; } 简单的比大小问题,将时间都换算成秒,进行比较。 来源: https://www.cnblogs

单链表排序

天涯浪子 提交于 2020-02-08 11:16:15
leetcode148链表排序 归并排序 快排链表 原题链接:https://leetcode-cn.com/problems/sort-list/ 归并排序 /** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class Solution { public ListNode sortList ( ListNode head ) { return head == null ? null : digui ( head ) ; } private ListNode digui ( ListNode head ) //找到中间节点进行分治 { if ( head . next == null ) return head ; ListNode mid = null , low = head , high = head ; while ( high != null && high . next != null ) { mid = low ; low = low . next ; high = high . next . next ; } //找到中间节点,进行后续归并 mid .

刷题34. Find First and Last Position of Element in Sorted Array

六眼飞鱼酱① 提交于 2020-02-08 09:04:07
一、题目说明 题目是34. Find First and Last Position of Element in Sorted Array,查找一个给定值的起止位置,时间复杂度要求是Olog(n)。题目的难度是Medium! 二、我的解答 这个题目还是二分查找(折半查找),稍微变化一下。target==nums[mid]后,需要找前面、后面的值是否=target。 一次写出来,bug free,熟能生巧!怎一个爽字了得! #include<iostream> #include<vector> using namespace std; class Solution{ public: vector<int> searchRange(vector<int>& nums, int target){ vector<int> res; if(nums.size()<1){ res.push_back(-1); res.push_back(-1); return res; } int begin = 0; int end = nums.size()-1; int mid = -1; while(begin <= end){ mid = (begin + end) / 2; if(nums[mid] == target){ begin = mid; while(begin>0 && nums

c/c++

*爱你&永不变心* 提交于 2020-02-08 06:23:33
#c/c++ #####头文件 stdio.h c语言的标准输入输出,常用 printf;scanf iostream c++语言的标准输入输出,重用 cin;cout algorithm c++的常用算法头文件,如 sort;qsort #####数组处理 memcpy 数组a复制k个元素到数组b: memcpy(b,a,sizeof(int)*k); 数组a全部复制到数组b: memcpy(b,a,sizeof(a)); memset 数组a清0:``` memset(a,0,sizeof(a)); > >这里注意一点,memset对int数组赋初值时**只能赋值0**,其他数都不能赋值,++因为memset赋值的单位是字节,而int是4个字节,所以你赋值0,每字节都是0.所以合起来4个字节也是0,但是赋值其他的数,4个字节合起来就不是原来的数了++。(所以memset大多用来给char数组赋初值,因为char是一个字节) * #####数学计算 + pow >```pow(double a,double b);``` >头文件:```<math.h>``` > 功能:计算a的b次方 * #####字符处理 + sprintf >printf输出到屏幕,fprintf输出到文件,sprintf输出到字符串 >```sprintf(a,"%d%d%d",a,b,c); ```/

【LeetCode】046. Permutations

折月煮酒 提交于 2020-02-08 04:06:09
题目: Given a collection of distinct numbers, return all possible permutations. For example, [1,2,3] have the following permutations: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ]    题解:   之前解过Next Permutation,故这个题可以重复调用nextPermutation函数产生全排列 Solution 1 () class Solution { public: void nextPermutation(vector<int>& nums) { int n = nums.size(); for(int i=n-2; i>=0; --i) { if(nums[i]>=nums[i+1]) continue; int j = n-1; for(; j>i; --j) { if(nums[j]>nums[i]) break; } swap(nums[i], nums[j]); reverse(nums.begin()+i+1, nums.end()); return; } reverse(nums.begin(), nums.end()); } vector<vector

C++STL中lower_bound() 和 upper_bound()二分查找

时间秒杀一切 提交于 2020-02-08 02:39:44
lower_bound( )和upper_bound( )都是利用二分查找的方法在一个 排好序的数组 中进行查找的。 通常用sort函数从小到大排序。 在从小到大的排序数组中, lower_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。 upper_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。 来源: https://www.cnblogs.com/transmigration-zhou/p/12275365.html

剑指offer11-20

夙愿已清 提交于 2020-02-07 04:12:26
11. 旋转数组的最小值 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。 思路:由于旋转数组的特性,尾元素肯定是小于首元素的(当不考虑重复值时)。所以,每次找中间值,如果中间值大于首元素,则中元素为前面那段,相反,则为后面那段。截止条件为s,e相差1。 其次,考虑旋转0个的情况,返回的是第一个。在其次,考虑有重复的情况。如{1,0,1,1,1},{1,1,1,0,1}都可以看成{0,1,1,1,1}的旋转,故此时使用循环依次查找。 代码: class Solution { public: int minNumberInRotateArray ( vector < int > rotateArray ) { if ( rotateArray.size ( ) == 0 ) //注意vector的长度并不是array.length return 0 ; int length = rotateArray.size ( ) ; int s = 0, e = length - 1 ; int mid = 0, min ; while ( rotateArray [