├── .DS_Store ├── README.md ├── SQL ├── demo1179 ├── demo175 ├── demo176 ├── demo177 ├── demo178 ├── demo180 ├── demo181 ├── demo182 ├── demo183 ├── demo184 ├── demo185 ├── demo196 ├── demo197 ├── demo595 ├── demo596 ├── demo601 ├── demo620 ├── demo626 └── demo627 ├── demo001-100 ├── .DS_Store ├── demo001.java ├── demo002.java ├── demo003.java ├── demo005.java ├── demo007.java ├── demo008.java ├── demo009.java ├── demo011.java ├── demo013.java ├── demo014.java ├── demo017.java ├── demo019.java ├── demo020.java ├── demo021.java ├── demo022.java ├── demo026.java ├── demo027.java ├── demo033.java ├── demo034.java ├── demo036.java ├── demo038.java ├── demo039.java ├── demo040.java ├── demo046.java ├── demo047.java ├── demo048.java ├── demo049.java ├── demo050.java ├── demo053.java ├── demo054.java ├── demo055.java ├── demo056.java ├── demo059.java ├── demo061.java ├── demo062.java ├── demo064.java ├── demo066.java ├── demo069.java ├── demo070.java ├── demo073.java ├── demo075.java ├── demo077.java ├── demo078.java ├── demo079.java ├── demo083.java ├── demo084.java ├── demo088.java ├── demo089.java ├── demo090.java ├── demo091.java ├── demo094.java ├── demo098.java └── demo100.java ├── demo101-200 ├── demo101.java ├── demo102.java ├── demo103.java ├── demo104.java ├── demo108.java ├── demo110.java ├── demo112.java ├── demo113.java ├── demo118.java ├── demo119.java ├── demo121.java ├── demo122.java ├── demo125.java ├── demo129.java ├── demo136.java ├── demo139.java ├── demo141.java ├── demo142.java ├── demo148.java ├── demo151.java ├── demo152.java ├── demo153.java ├── demo154.java ├── demo155.java ├── demo160.java ├── demo162.java ├── demo169.java ├── demo171.java ├── demo172.java ├── demo179.java ├── demo189.java ├── demo191.java ├── demo198.java └── demo200.java ├── demo201-300 ├── .DS_Store ├── demo202.java ├── demo204.java ├── demo206.java ├── demo215.java ├── demo217.java ├── demo219.java ├── demo222.java ├── demo226.java ├── demo230.java ├── demo231.java ├── demo233.java ├── demo234.java ├── demo235.java ├── demo236.java ├── demo237.java ├── demo238.java ├── demo240.java ├── demo242.java ├── demo263.java ├── demo264.java ├── demo268.java ├── demo279.java ├── demo283.java ├── demo287.java ├── demo292.java └── demo300.java ├── demo301-400 ├── demo326.java ├── demo328.java ├── demo338.java ├── demo342.java ├── demo343.java ├── demo344.java ├── demo347.java ├── demo349.java ├── demo350.java ├── demo371.java ├── demo378.java ├── demo387.java └── demo400.java ├── demo401-500 ├── demo412.java ├── demo448.java ├── demo461.java └── demo485.java ├── demo501-600 ├── demo509.java ├── demo520.java ├── demo543.java ├── demo557.java ├── demo561.java └── demo581.java ├── demo601-700 ├── demo617.java └── demo657.java ├── demo701-800 └── demo771.java ├── demo901-1000 └── demo946.java ├── design_pattern ├── .DS_Store ├── .idea │ ├── .gitignore │ ├── misc.xml │ ├── modules.xml │ ├── uiDesigner.xml │ └── vcs.xml ├── design_pattern.iml ├── out │ └── production │ │ └── design_pattern │ │ ├── AbstractFactory │ │ ├── AbstractFactory │ │ ├── AbstractFactory.class │ │ ├── AbstractFactory_UML.png │ │ ├── ConcreteFactoryA.class │ │ ├── Product.class │ │ ├── concreteProductA.class │ │ └── concreteProductB.class │ │ ├── Adapter │ │ ├── Adapte │ │ ├── Adaptee.class │ │ ├── AdapterDemo │ │ │ ├── ElectricAdapter.class │ │ │ ├── ElectricMotor.class │ │ │ ├── Motor.class │ │ │ ├── MotorAdapterTest.class │ │ │ ├── OpticalAdapter.class │ │ │ └── OpticalMotor.class │ │ ├── AdapterTest.class │ │ ├── Adapter_UML.png │ │ ├── ClassAdapter.class │ │ └── Target.class │ │ ├── Decorator │ │ ├── Component.class │ │ ├── ConcreteComponent.class │ │ ├── ConcreteDecorator.class │ │ ├── Decorate_UML.png │ │ ├── Decorator │ │ ├── Decorator.class │ │ └── DecoratorTest.class │ │ ├── FactoryMethod │ │ ├── AbstractFactory.class │ │ ├── FactoryMethod │ │ ├── Factory_Method_UML.png │ │ ├── Factory_Test.class │ │ ├── Product.class │ │ ├── concreteFactoryA.class │ │ ├── concreteFactoryB.class │ │ ├── concreteProductA.class │ │ └── concreteProductB.class │ │ ├── META-INF │ │ └── design_pattern.kotlin_module │ │ ├── Observer │ │ ├── ConcreteObserver1.class │ │ ├── ConcreteObserver2.class │ │ ├── ConcreteSubject.class │ │ ├── Observer │ │ ├── Observer.class │ │ ├── ObserverDemo │ │ │ ├── Bear.class │ │ │ ├── Bull.class │ │ │ ├── OilFuture.class │ │ │ └── Tests.class │ │ ├── ObserverTest.class │ │ ├── Observer_UML.png │ │ └── Subject.class │ │ ├── Prototype │ │ ├── Prototype │ │ ├── PrototypeTest.class │ │ ├── Prototype_UML.png │ │ └── Realizetype.class │ │ ├── Proxy │ │ ├── Proxy │ │ ├── Proxy.class │ │ ├── ProxyTest.class │ │ ├── Proxy_UML.png │ │ ├── RealSubject.class │ │ └── Subject.class │ │ ├── Singleton │ │ ├── HungrySingleton.class │ │ ├── LazySingleton.class │ │ ├── Singleton │ │ ├── SingletonDemo$Sunhongwei.class │ │ ├── SingletonDemo.class │ │ └── Singleton_UML.png │ │ ├── Strategy │ │ ├── ConcreteStrategyA.class │ │ ├── ConcreteStrategyB.class │ │ ├── Context.class │ │ ├── Strategy │ │ ├── Strategy.class │ │ ├── StrategyTest.class │ │ └── Strategy_UML.png │ │ └── TemplateMethod │ │ ├── AbstractClass.class │ │ ├── ConcreteClass.class │ │ ├── TemplateMethod │ │ ├── TemplateMethodTest.class │ │ └── TemplateMethod_UML.png └── src │ ├── .DS_Store │ ├── AbstractFactory │ ├── AbstractFactory │ ├── AbstractFactory.java │ ├── AbstractFactory_UML.png │ ├── ConcreteFactoryA.java │ ├── Product.java │ ├── concreteProductA.java │ └── concreteProductB.java │ ├── Adapter │ ├── .DS_Store │ ├── Adapte │ ├── Adaptee.java │ ├── AdapterDemo │ │ ├── ElectricAdapter.java │ │ ├── ElectricMotor.java │ │ ├── Motor.java │ │ ├── MotorAdapterTest.java │ │ ├── OpticalAdapter.java │ │ └── OpticalMotor.java │ ├── AdapterTest.java │ ├── Adapter_UML.png │ ├── ClassAdapter.java │ └── Target.java │ ├── Decorator │ ├── .DS_Store │ ├── Component.java │ ├── ConcreteComponent.java │ ├── ConcreteDecorator.java │ ├── Decorate_UML.png │ ├── Decorator │ ├── Decorator.java │ └── DecoratorTest.java │ ├── FactoryMethod │ ├── AbstractFactory.java │ ├── FactoryMethod │ ├── Factory_Method_UML.png │ ├── Factory_Test.java │ ├── Product.java │ ├── concreteFactoryA.java │ ├── concreteFactoryB.java │ ├── concreteProductA.java │ └── concreteProductB.java │ ├── Observer │ ├── ConcreteObserver1.java │ ├── ConcreteObserver2.java │ ├── ConcreteSubject.java │ ├── Observer │ ├── Observer.java │ ├── ObserverDemo │ │ ├── Bear.java │ │ ├── Bull.java │ │ ├── OilFuture.java │ │ └── Tests.java │ ├── ObserverTest.java │ ├── Observer_UML.png │ └── Subject.java │ ├── Prototype │ ├── Prototype │ ├── PrototypeTest.java │ ├── Prototype_UML.png │ └── Realizetype.java │ ├── Proxy │ ├── Proxy │ ├── Proxy.java │ ├── ProxyTest.java │ ├── Proxy_UML.png │ ├── RealSubject.java │ └── Subject.java │ ├── Singleton │ ├── .DS_Store │ ├── HungrySingleton.java │ ├── LazySingleton.java │ ├── Singleton │ ├── SingletonDemo.java │ └── Singleton_UML.png │ ├── Strategy │ ├── ConcreteStrategyA.java │ ├── ConcreteStrategyB.java │ ├── Context.java │ ├── Strategy │ ├── Strategy.java │ ├── StrategyTest.java │ └── Strategy_UML.png │ └── TemplateMethod │ ├── AbstractClass.java │ ├── ConcreteClass.java │ ├── TemplateMethod │ ├── TemplateMethodTest.java │ └── TemplateMethod_UML.png ├── offer ├── m03.java ├── m05.java ├── m06.java ├── m09.java ├── m13.java ├── m17.java ├── m21.java ├── m26.java ├── m32_1.java ├── m38.java ├── m40.java ├── m45.java ├── m46.java ├── m47.java ├── m50.java ├── m53_1.java ├── m53_2.java ├── m54.java ├── m56_1.java ├── m56_2.java ├── m57_1.java ├── m58_2.java ├── m60.java ├── m61.java ├── m62.java ├── m64.java ├── m65.java └── m66.java └── sorting ├── .idea ├── .gitignore ├── misc.xml ├── modules.xml └── vcs.xml ├── out └── production │ └── sorting │ ├── BinarySearch.class │ ├── BubbleSort.class │ ├── BucketSort.class │ ├── InsertSort.class │ ├── MergeSort.class │ ├── QuickSort.class │ ├── ShellSort.class │ └── SortTest.class ├── sorting.iml └── src ├── BinarySearch.java ├── BubbleSort.java ├── BucketSort.java ├── InsertSort.java ├── MergeSort.java ├── QuickSort.java ├── ShellSort.java └── SortTest.java /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/.DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # my_leetcode_algorithm 2 | some solutions for Leetcode algorithm questions by myself 3 | -------------------------------------------------------------------------------- /SQL/demo175: -------------------------------------------------------------------------------- 1 | demo175 2 | 3 | 表1: Person 4 | 5 | +-------------+---------+ 6 | | 列名 | 类型 | 7 | +-------------+---------+ 8 | | PersonId | int | 9 | | FirstName | varchar | 10 | | LastName | varchar | 11 | +-------------+---------+ 12 | PersonId 是上表主键 13 | 表2: Address 14 | 15 | +-------------+---------+ 16 | | 列名 | 类型 | 17 | +-------------+---------+ 18 | | AddressId | int | 19 | | PersonId | int | 20 | | City | varchar | 21 | | State | varchar | 22 | +-------------+---------+ 23 | AddressId 是上表主键 24 | 25 | 编写一个 SQL 查询,满足条件:无论 person 是否有地址信息,都需要基于上述两表提供 person 的以下信息: 26 | FirstName, LastName, City, State 27 | 28 | 29 | _______________________________________________________________ 30 | 31 | 32 | 33 | 连接时保证一表存在,用left(right) join ... on... 34 | 35 | SELECT Person.FirstName,Person.LastName,Address.City,Address.State 36 | FROM Person 37 | LEFT JOIN Address 38 | ON Person.PersonId=Address.PersonId; -------------------------------------------------------------------------------- /SQL/demo176: -------------------------------------------------------------------------------- 1 | demo176 2 | 3 | 编写一个 SQL 查询,获取 Employee 表中第二高的薪水(Salary) 。 4 | 5 | +----+--------+ 6 | | Id | Salary | 7 | +----+--------+ 8 | | 1 | 100 | 9 | | 2 | 200 | 10 | | 3 | 300 | 11 | +----+--------+ 12 | 例如上述 Employee 表,SQL查询应该返回 200 作为第二高的薪水。如果不存在第二高的薪水,那么查询应返回 null。 13 | 14 | +---------------------+ 15 | | SecondHighestSalary | 16 | +---------------------+ 17 | | 200 | 18 | +---------------------+ 19 | 20 | _______________________________________________________________ 21 | (1) select * from table limit 2,1; 含义是跳过2条取出1条数据 22 | (2) select * from table limit 2 offset 1; 含义是从第1条(不包括)数据开始取出2条数据 23 | 24 | 25 | 26 | SELECT 27 | IFNULL 28 | ( 29 | (SELECT distinct(Salary) FROM Employee 30 | ORDER BY Salary DESC 31 | LIMIT 1 offset 1) 32 | ,null) 33 | as SecondHighestSalary; -------------------------------------------------------------------------------- /SQL/demo177: -------------------------------------------------------------------------------- 1 | demo177 2 | 3 | 编写一个 SQL 查询,获取 Employee 表中第 n 高的薪水(Salary)。 4 | 5 | +----+--------+ 6 | | Id | Salary | 7 | +----+--------+ 8 | | 1 | 100 | 9 | | 2 | 200 | 10 | | 3 | 300 | 11 | +----+--------+ 12 | 例如上述 Employee 表,n = 2 时,应返回第二高的薪水 200。如果不存在第 n 高的薪水,那么查询应返回 null。 13 | 14 | +------------------------+ 15 | | getNthHighestSalary(2) | 16 | +------------------------+ 17 | | 200 | 18 | +------------------------+ 19 | 20 | _______________________________________________________________ 21 | 先判断n的大小,取第n个时用limit n-1,1 //跳过n-1个数后,取第n个 22 | 23 | 24 | 25 | CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT 26 | BEGIN 27 | SET N=N-1; 28 | RETURN( 29 | SELECT IFNULL( 30 | ( 31 | SELECT DISTINCT(Salary) 32 | FROM Employee 33 | ORDER BY Salary DESC 34 | LIMIT N,1 35 | ) 36 | ,null) as getNthHighestSalary 37 | ); 38 | END -------------------------------------------------------------------------------- /SQL/demo178: -------------------------------------------------------------------------------- 1 | demo178 2 | 3 | 编写一个 SQL 查询来实现分数排名。如果两个分数相同,则两个分数排名(Rank)相同。请注意,平分后的下一个名次应该是下一个连续的整数值。换句话说,名次之间不应该有“间隔”。 4 | 5 | +----+-------+ 6 | | Id | Score | 7 | +----+-------+ 8 | | 1 | 3.50 | 9 | | 2 | 3.65 | 10 | | 3 | 4.00 | 11 | | 4 | 3.85 | 12 | | 5 | 4.00 | 13 | | 6 | 3.65 | 14 | +----+-------+ 15 | 例如,根据上述给定的 Scores 表,你的查询应该返回(按分数从高到低排列): 16 | 17 | +-------+------+ 18 | | Score | Rank | 19 | +-------+------+ 20 | | 4.00 | 1 | 21 | | 4.00 | 1 | 22 | | 3.85 | 2 | 23 | | 3.65 | 3 | 24 | | 3.65 | 3 | 25 | | 3.50 | 4 | 26 | +-------+------+ 27 | 28 | _______________________________________________________________ 29 | 先拆成两表,对于a表中的每一个分数score,找出b表中有多少个大于或等于该分数的不同的分数,然后按降序排列 30 | 31 | SELECT a.Score as Score, 32 | (SELECT COUNT(distinct b.Score) from Scores b where b.Score>=a.Score)as Rank 33 | FROM Scores a 34 | ORDER BY Rank ASC; 35 | 36 | -------------------------------------------------------------------------------- /SQL/demo180: -------------------------------------------------------------------------------- 1 | demo180 2 | 3 | 编写一个 SQL 查询,查找所有至少连续出现三次的数字。 4 | 5 | +----+-----+ 6 | | Id | Num | 7 | +----+-----+ 8 | | 1 | 1 | 9 | | 2 | 1 | 10 | | 3 | 1 | 11 | | 4 | 2 | 12 | | 5 | 1 | 13 | | 6 | 2 | 14 | | 7 | 2 | 15 | +----+-----+ 16 | 例如,给定上面的 Logs 表, 1 是唯一连续出现至少三次的数字。 17 | 18 | +-----------------+ 19 | | ConsecutiveNums | 20 | +-----------------+ 21 | | 1 | 22 | +-----------------+ 23 | 24 | _______________________________________________________________ 25 | 26 | 比较连续三次的情况,等于构建三张相同的表进行比较:(并用DISTINCT保证结果不重复) 27 | 28 | SELECT DISTINCT Num as ConsecutiveNums 29 | FROM Logs A,Logs B,Logs C 30 | WHERE 31 | A.Id=B.Id-1 AND A.Num=B.Num 32 | AND A.Id=C.Id-2 AND A.Num=C.Num; -------------------------------------------------------------------------------- /SQL/demo181: -------------------------------------------------------------------------------- 1 | demo181 2 | 3 | Employee 表包含所有员工,他们的经理也属于员工。每个员工都有一个 Id,此外还有一列对应员工的经理的 Id。 4 | 5 | +----+-------+--------+-----------+ 6 | | Id | Name | Salary | ManagerId | 7 | +----+-------+--------+-----------+ 8 | | 1 | Joe | 70000 | 3 | 9 | | 2 | Henry | 80000 | 4 | 10 | | 3 | Sam | 60000 | NULL | 11 | | 4 | Max | 90000 | NULL | 12 | +----+-------+--------+-----------+ 13 | 给定 Employee 表,编写一个 SQL 查询,该查询可以获取收入超过他们经理的员工的姓名。在上面的表格中,Joe 是唯一一个收入超过他的经理的员工。 14 | 15 | +----------+ 16 | | Employee | 17 | +----------+ 18 | | Joe | 19 | +----------+ 20 | 21 | _______________________________________________________________ 22 | 23 | 1.拆成两个表再用ManagerId=Id整合一起时比较Salary 24 | 25 | SELECT A.Name as Employee 26 | FROM Employee as A,Employee as B 27 | WHERE A.ManagerId=B.Id 28 | AND A.Salary>B.Salary; 29 | 30 | 2.用JOIN...ON整合一起 31 | SELECT A.Name as Employee 32 | FROM Employee as A JOIN Employee as B 33 | ON A.ManagerId=B.Id 34 | AND A.Salary>B.Salary; -------------------------------------------------------------------------------- /SQL/demo182: -------------------------------------------------------------------------------- 1 | demo182 2 | 3 | #编写一个 SQL 查询,查找 Person 表中所有重复的电子邮箱。 4 | +----+---------+ 5 | | Id | Email | 6 | +----+---------+ 7 | | 1 | a@b.com | 8 | | 2 | c@d.com | 9 | | 3 | a@b.com | 10 | +----+---------+ 11 | 12 | 根据以上输入,你的查询应返回以下结果: 13 | 14 | +---------+ 15 | | Email | 16 | +---------+ 17 | | a@b.com | 18 | +---------+ 19 | 说明:所有电子邮箱都是小写字母。 20 | _______________________________________________________________ 21 | 22 | 1.group by和临时表 23 | SELECT Email From 24 | ( 25 | SELECT Email,count(Email) as num 26 | FROM Person 27 | GROUP BY Email 28 | )as NewPerson 29 | WHERE num>1; 30 | 31 | 32 | 2.group by和 Having 33 | //在 SQL 中增加 HAVING 子句原因是,WHERE 关键字无法与聚合函数一起使用。 34 | HAVING 子句可以筛选分组后的各组数据。 35 | 36 | 37 | SELECT Email 38 | FROM Person 39 | GROUP BY Email 40 | HAVING COUNT(Email)>1; 41 | -------------------------------------------------------------------------------- /SQL/demo183: -------------------------------------------------------------------------------- 1 | demo183 2 | 3 | 某网站包含两个表,Customers 表和 Orders 表。编写一个 SQL 查询,找出所有从不订购任何东西的客户。 4 | 5 | Customers 表: 6 | 7 | +----+-------+ 8 | | Id | Name | 9 | +----+-------+ 10 | | 1 | Joe | 11 | | 2 | Henry | 12 | | 3 | Sam | 13 | | 4 | Max | 14 | +----+-------+ 15 | Orders 表: 16 | 17 | +----+------------+ 18 | | Id | CustomerId | 19 | +----+------------+ 20 | | 1 | 3 | 21 | | 2 | 1 | 22 | +----+------------+ 23 | 例如给定上述表格,你的查询应返回: 24 | 25 | +-----------+ 26 | | Customers | 27 | +-----------+ 28 | | Henry | 29 | | Max | 30 | +-----------+ 31 | 32 | _______________________________________________________________ 33 | 34 | 35 | 1.NOT IN: 36 | 37 | SELECT Customers.Name as Customers 38 | FROM Customers 39 | WHERE Customers.Id 40 | NOT IN 41 | ( 42 | SELECT CustomerId FROM Orders 43 | ); 44 | 45 | 46 | 47 | 2.LEFT JOIN: 48 | 左连接(以左表为核心): 从左表(table1)返回所有的行,即使右表(table2)中没有匹配。如果右表中没有匹配,则结果为 NULL。 49 | 50 | SELECT Customers.Name as Customers 51 | FROM Customers 52 | LEFT JOIN Orders 53 | ON Customers.Id=Orders.CustomerId 54 | WHERE Orders.CustomerId is null; 55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /SQL/demo197: -------------------------------------------------------------------------------- 1 | demo197 2 | 3 | 给定一个 Weather 表,编写一个 SQL 查询,来查找与之前(昨天的)日期相比温度更高的所有日期的 Id。 4 | 5 | +---------+------------------+------------------+ 6 | | Id(INT) | RecordDate(DATE) | Temperature(INT) | 7 | +---------+------------------+------------------+ 8 | | 1 | 2015-01-01 | 10 | 9 | | 2 | 2015-01-02 | 25 | 10 | | 3 | 2015-01-03 | 20 | 11 | | 4 | 2015-01-04 | 30 | 12 | +---------+------------------+------------------+ 13 | 例如,根据上述给定的 Weather 表格,返回如下 Id: 14 | 15 | +----+ 16 | | Id | 17 | +----+ 18 | | 2 | 19 | | 4 | 20 | +----+ 21 | 22 | _______________________________________________________________ 23 | 24 | 1.比较日期格式数据,用 DATEDIFF 函数: DATEDIFF(日期1, 日期2):得到的结果是日期1与日期2相差的天数。 25 | 2.把表自身拆成两个表进行比较 26 | 27 | SELECT A.Id as Id 28 | From Weather as A 29 | JOIN Weather as B 30 | On DATEDIFF(A.DATE,B.DATE)=1 31 | AND a.Temperature>B.Temperature; 32 | -------------------------------------------------------------------------------- /SQL/demo596: -------------------------------------------------------------------------------- 1 | demo596 2 | 3 | 有一个courses 表 ,有: student (学生) 和 class (课程)。 4 | 5 | 请列出所有超过或等于5名学生的课。 6 | 7 | 例如,表: 8 | 9 | +---------+------------+ 10 | | student | class | 11 | +---------+------------+ 12 | | A | Math | 13 | | B | English | 14 | | C | Math | 15 | | D | Biology | 16 | | E | Math | 17 | | F | Computer | 18 | | G | Math | 19 | | H | Math | 20 | | I | Math | 21 | +---------+------------+ 22 | 应该输出: 23 | 24 | +---------+ 25 | | class | 26 | +---------+ 27 | | Math | 28 | +---------+ 29 | Note: 30 | 学生在每个课中不应被重复计算。 31 | 32 | _______________________________________________________________ 33 | 用distinct 防止学生被重复计算 34 | 35 | 36 | 1.用Having筛选: 37 | SELECT class 38 | FROM courses 39 | GROUP BY class 40 | HAVING COUNT(DISTINCT student)>=5; 41 | 42 | 2.构建临时表: 43 | SELECT class 44 | FROM 45 | ( //临时表 46 | SELECT class,COUNT(DISTINCT student) as num 47 | FROM courses 48 | GROUP BY class 49 | )as classnum 50 | WHERE num>1; 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /SQL/demo626: -------------------------------------------------------------------------------- 1 | demo626 2 | 3 | 小美是一所中学的信息科技老师,她有一张 seat 座位表,平时用来储存学生名字和与他们相对应的座位 id。 4 | 其中纵列的 id 是连续递增的 5 | 小美想改变相邻俩学生的座位。 6 | 7 | 示例: 8 | 9 | +---------+---------+ 10 | | id | student | 11 | +---------+---------+ 12 | | 1 | Abbot | 13 | | 2 | Doris | 14 | | 3 | Emerson | 15 | | 4 | Green | 16 | | 5 | Jeames | 17 | +---------+---------+ 18 | 假如数据输入的是上表,则输出结果如下: 19 | 20 | +---------+---------+ 21 | | id | student | 22 | +---------+---------+ 23 | | 1 | Doris | 24 | | 2 | Abbot | 25 | | 3 | Green | 26 | | 4 | Emerson | 27 | | 5 | Jeames | 28 | +---------+---------+ 29 | 注意: 30 | 31 | 如果学生人数是奇数,则不需要改变最后一个同学的座位。 32 | 用case...when... 分析id的奇偶性作出调整 33 | 34 | 35 | SELECT ( 36 | CASE 37 | WHEN mod(id,2)=1 AND id=counts THEN id 38 | WHEN mod(id,2)=1 And id!=counts THEN id+1 39 | ELSE id-1 40 | END 41 | )as id,student 42 | FROM seat,(SELECT COUNT(*) as counts FROM seat) as seat_counts 43 | ORDER BY id ASC; 44 | 45 | -------------------------------------------------------------------------------- /SQL/demo627: -------------------------------------------------------------------------------- 1 | demo627 2 | 3 | 给定一个 salary 表,如下所示,有 m = 男性 和 f = 女性 的值。交换所有的 f 和 m 值(例如,将所有 f 值更改为 m,反之亦然)。要求只使用一个更新(Update)语句,并且没有中间的临时表。 4 | 5 | 注意,您必只能写一个 Update 语句,请不要编写任何 Select 语句。 6 | 7 | 例如: 8 | 9 | | id | name | sex | salary | 10 | |----|------|-----|--------| 11 | | 1 | A | m | 2500 | 12 | | 2 | B | f | 1500 | 13 | | 3 | C | m | 5500 | 14 | | 4 | D | f | 500 | 15 | 运行你所编写的更新语句之后,将会得到以下表: 16 | 17 | | id | name | sex | salary | 18 | |----|------|-----|--------| 19 | | 1 | A | f | 2500 | 20 | | 2 | B | m | 1500 | 21 | | 3 | C | f | 5500 | 22 | | 4 | D | m | 500 | 23 | 24 | _______________________________________________________________ 25 | 26 | 27 | 1.case...when... 28 | 29 | UPDATE salary 30 | SET 31 | sex=CASE sex 32 | WHEN 'm' THEN 'f' 33 | ELSE 'm' 34 | END; 35 | 36 | 37 | 2.ASCII互转 !!! 38 | UPDATE salary 39 | SET 40 | sex = char(ascii('m') + ascii('f') - ascii(sex)); 41 | //变换前后总和一样 42 | -------------------------------------------------------------------------------- /demo001-100/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/demo001-100/.DS_Store -------------------------------------------------------------------------------- /demo001-100/demo001.java: -------------------------------------------------------------------------------- 1 | package demo001_100; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/12 下午3:39 6 | * File Description:两数之和:给定一个整数数组 nums 和一个目标值 target, 7 | * 请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。 8 | * 9 | * 10 | * 1.暴力遍历即可 11 | * 2.两边遍历hash表,第一遍将target-nums[i]放入hash表,第二遍监察nums[i]是否在表里 12 | */ 13 | public class demo001 { 14 | public int[] twoSum(int[] nums, int target) { 15 | int[] out=new int[2]; 16 | for(int i=0;i map=new HashMap(); 17 | int maxLength=0; 18 | for(int end=0,start=0;end=0;i--){ 16 | for(int j=i;jresult.length()){ 21 | result=s.substring(i,j+1); 22 | } 23 | } 24 | } 25 | } 26 | } 27 | return result; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /demo001-100/demo007.java: -------------------------------------------------------------------------------- 1 | package demo001_100; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/12 下午7:57 6 | * File Description:整数反转:给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。 7 | * 8 | * 9 | * 设置个数组依次保存各位数字,再反过来加上 10 | */ 11 | public class demo007 { 12 | public static int reverse(int x){ 13 | int flag=1,p=0; 14 | int[] out=new int[13]; 15 | if(x<0){ 16 | flag=-1; 17 | } 18 | x=Math.abs(x); 19 | while(x>0){ 20 | out[p++]=x%10; 21 | x=x/10; 22 | } 23 | long result=0; 24 | for(int i=0;iMath.pow(2,31)-1 || result<-Math.pow(2,31)){ 28 | return 0; 29 | } 30 | return (int)result * flag; 31 | 32 | } 33 | 34 | public static void main(String[] args) { 35 | int x=1534236469; 36 | int result=reverse(x); 37 | System.out.println(result); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /demo001-100/demo009.java: -------------------------------------------------------------------------------- 1 | package demo001_100; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/12 下午8:02 6 | * File Description:回文数:判断一个整数是否是回文数。回文数是指正序(从左向右)和 7 | * 倒序(从右向左)读都是一样的整数。 8 | * 9 | * 10 | * 转换成字符串,然后两个指针分别从前面和从后面遍历 11 | */ 12 | public class demo009 { 13 | public static boolean isPalindrome(int x) { 14 | if(x<0){ 15 | return false; 16 | } 17 | String s=x+""; //把整数变成字符串 18 | char in[]=s.toCharArray(); //把 19 | int i=0,j=s.length()-1; 20 | while(i<=j){ 21 | if(in[i]!=in[j]){ 22 | return false; 23 | } 24 | i++; 25 | j--; 26 | 27 | } 28 | return true; 29 | } 30 | 31 | public static void main(String[] args) { 32 | int x=121; 33 | boolean flag=isPalindrome(x); 34 | System.out.println(flag); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /demo001-100/demo011.java: -------------------------------------------------------------------------------- 1 | package demo001_100; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/12 下午8:12 6 | * File Description:盛最多水的容器: 给定 n 个非负整数 a1,a2,...,an, 7 | * 每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线, 8 | * 垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线, 9 | * 使得它们与 x 轴共同构成的容器可以容纳最多的水。 10 | * 11 | * 12 | * 设置两个指针,一前一后遍历 13 | * 14 | */ 15 | public class demo011 { 16 | //盛最多水的容器:双指针法 17 | public static int maxArea(int[] height) { 18 | int area=0,left=0,right=height.length-1; 19 | while(left results=new ArrayList<>(); 17 | public List generateParenthesis(int n) { 18 | trackback("",n,0,0); 19 | return results; 20 | } 21 | 22 | public void trackback(String s,int n,int numleft,int numright){ 23 | if(s.length()==n*2){ 24 | results.add(s); 25 | return; 26 | } 27 | //如果左括号没到上限,可以加入左括号 28 | if(numleftnumright) trackback(s+')',n,numleft,numright+1); 31 | 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /demo001-100/demo026.java: -------------------------------------------------------------------------------- 1 | package demo001_100; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/12 下午9:44 6 | * File Description: 删除排序数组中的重复项: 给定一个排序数组,你需要在原地删除重复出现的元素, 7 | * 使得每个元素只出现一次,返回移除后数组的新长度。 8 | * 9 | * 10 | * 设置两个指针,一个用于遍历整个数组,一个用于保存新数组前n个不同的元素 11 | */ 12 | public class demo026 { 13 | public static int removeDuplicates(int[] nums) { 14 | int i=0,j=1; 15 | if(nums.length<=1){ 16 | return nums.length; 17 | }else{ 18 | while(jtarget){ 21 | r=mid-1; 22 | }else if(nums[mid]=0 && nums[p]==target) p--; 33 | ans[0]=p+1; 34 | break; 35 | } 36 | } 37 | return ans; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /demo001-100/demo048.java: -------------------------------------------------------------------------------- 1 | package demo001_100; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/19 下午1:15 6 | * File Description:旋转图像:给定一个 n × n 的二维矩阵表示一个图像。 7 | * 将图像顺时针旋转 90 度。 8 | * 9 | * 10 | * 1.先将矩阵转置 2.将每一行反转 11 | */ 12 | public class demo048 { 13 | public void rotate(int[][] matrix) { 14 | int n=matrix.length; 15 | int temp; // 交换设置的临时变量 16 | 17 | //矩阵转置 18 | for(int i=0;i> groupAnagrams(String[] strs) { 16 | if(strs.length==0) return new ArrayList(); 17 | Map ans=new HashMap(); 18 | for(String s:strs){ 19 | char[] c=s.toCharArray(); 20 | Arrays.sort(c); 21 | String key=String.valueOf(c); //排序后再转为字符串 22 | if(!ans.containsKey(key)){ 23 | ans.put(key,new ArrayList()); //没有的话重新创建一个ArrayList 24 | } 25 | ans.get(key).add(s); 26 | } 27 | return new ArrayList(ans.values()); //将hashmap的value转化为ArrayList 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /demo001-100/demo050.java: -------------------------------------------------------------------------------- 1 | package demo001_100; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/19 下午1:30 6 | * File Description:Pow(x, n):实现 pow(x, n) ,即计算 x 的 n 次幂函数。 7 | * 8 | * 9 | * 尽可能的减少运算次数:比如x^5: (x^2)^2 * x 10 | * 考虑用递归实现这一过程 11 | */ 12 | public class demo050 { 13 | public double myPow(double x, int n) { 14 | switch (n){ 15 | case 0: 16 | return 1; 17 | case 1: 18 | return x; 19 | case -1: 20 | return 1/x; 21 | } 22 | double half,rest; 23 | 24 | half=myPow(x,n/2); 25 | rest=myPow(x,n%2); 26 | return half*half*rest; 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /demo001-100/demo053.java: -------------------------------------------------------------------------------- 1 | /** 2 | * @author:Sun Hongwei 3 | * @2020/2/12 下午2:36 4 | * File Description:最大子序和:给定一个整数数组nums,找到一个具有最大和的连续子数组 5 | * (子数组最少包含一个元素),返回其最大和。 6 | * Kadane 算法:向右遍历 7 | * (1)如果前面的sum大于0,结果有增益,直接加上 8 | * (2)如果前面的sum小于0,结果无增益,舍去 9 | * (3)每次比较更新当前最大值 10 | * 11 | */ 12 | public class demo053 { 13 | //最大自序和:动态规划 14 | public static int maxSubArray(int[] nums) { 15 | int maxsum=nums[0]; 16 | for(int i=1;i0)?nums[i-1]:0; //判断当前的前面自序之和 18 | maxsum=(nums[i]>maxsum)?nums[i]:maxsum; //更新最大值 19 | } 20 | return maxsum; 21 | } 22 | 23 | public static void main(String[] args) { 24 | int[] nums=new int[]{-2,-1}; 25 | int x=maxSubArray(nums); 26 | System.out.println(x); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /demo001-100/demo055.java: -------------------------------------------------------------------------------- 1 | package demo001_100; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/16 下午9:36 6 | * File Description:跳跃游戏: 给定一个非负整数数组,你最初位于数组的第一个位置。 7 | * 数组中的每个元素代表你在该位置可以跳跃的最大长度。 8 | * 判断是否能够到达最后一个位置。 9 | * 10 | * 11 | * 12 | * 从后往前遍历,判断是否能跳到该点,设置一个变量pos保存能保证到终点的最后一个节点位置 13 | * 14 | */ 15 | public class demo055 { 16 | public boolean canJump(int[] nums) { 17 | int pos=nums.length-1; 18 | for(int i=nums.length-1;i>=0;i--){ 19 | if(i+nums[i]>=pos){ 20 | pos=i; 21 | } 22 | } 23 | return pos==0; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /demo001-100/demo062.java: -------------------------------------------------------------------------------- 1 | package demo001_100; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/12 下午10:59 6 | * File Description:不同路径: 一个机器人位于一个 m x n 网格的左上角,试图达到网格的右下角 7 | * 问总共有多少条不同的路径? 8 | * 9 | * 组合问题:C(m-1,m+n-2) 10 | * !阶乘时可能数太大而导致越界->改成两个阶乘相除一起计算可以减小值 11 | */ 12 | public class demo062 { 13 | public int uniquePaths(int m, int n) { 14 | int k=Math.max(m,n),l=Math.min(m,n); 15 | //找出m,n较大的值和较小值,为下一步尽可能减少阶乘值的大小 16 | long result=faclong(m+n-2,k-1)/faclong(l-1,1); 17 | return (int)result; 18 | 19 | } 20 | //求两个阶乘相除(m!/n!) 21 | public long faclong(int m,int n){ 22 | if(m==0 || n==0) return 1; 23 | long num=1; 24 | int p=m; 25 | while(p!=n){ 26 | num*=(p--); 27 | } 28 | // System.out.println("m: "+m+"n: "+n+" : "+num); 29 | return num; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /demo001-100/demo064.java: -------------------------------------------------------------------------------- 1 | package demo001_100; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/21 下午2:59 6 | * File Description:最小路径和: 给定一个包含非负整数的 m x n 网格, 7 | * 请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。 8 | * 9 | * 10 | * 动态规划,除了边界:dp[i][j]=min(dp[i-1][j],dp[i][j-1])+grid[i][j]; 11 | * 12 | */ 13 | public class demo064 { 14 | public int minPathSum(int[][] grid) { 15 | for(int i=0;i=0;i--){ 12 | digits[i]++; 13 | if(digits[i]!=10){ 14 | return digits; 15 | }else{ 16 | digits[i]=0; 17 | } 18 | } 19 | digits=new int[len+1]; 20 | digits[0]=1; 21 | return digits; 22 | } 23 | public static void main(String[] args) { 24 | int[] nums=new int[]{1,2,3}; 25 | int[] tt=plusOne(nums); 26 | for(int i:tt){ 27 | System.out.println(i); 28 | } 29 | 30 | 31 | } 32 | 33 | 34 | } 35 | -------------------------------------------------------------------------------- /demo001-100/demo069.java: -------------------------------------------------------------------------------- 1 | /** 2 | * @author:Sun Hongwei 3 | * @2020/2/11 下午6:09 4 | * File Description:x 的平方根:实现 int sqrt(int x) 函数。 5 | * 计算并返回 x 的平方根,其中 x 是非负整数。 6 | * 7 | * 8 | * 牛顿迭代法:X(n+1)=(1/2)*(X(n)+x/X(n)) 9 | * 最后收敛结果为x的平方根 10 | */ 11 | public class demo069 { 12 | public int mySqrt(int x) { 13 | double x0=x,x1=(x0+x/x0)/2.0; 14 | while (Math.abs(x1-x0)>=1){ //前后两数相差小于1表示收敛 15 | x0=x1; 16 | x1=(x0+x/x0)/2.0; 17 | } 18 | return (int)x1; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /demo001-100/demo070.java: -------------------------------------------------------------------------------- 1 | import org.omg.Messaging.SYNC_WITH_TRANSPORT; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/9 下午10:16 6 | * File Description:爬楼梯:假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 7 | * 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? 8 | * 9 | * 动态规划:d[p]=d[p-1]+d[p-2] 10 | */ 11 | public class demo070 { 12 | public static int climbStairs(int n) { 13 | if(n<=0) return 0; 14 | if(n==1) return 1; 15 | int[] dp=new int[n]; 16 | dp[0]=1;dp[1]=2; 17 | for(int i=2;i col=new HashSet(); //列号 18 | Set row=new HashSet(); //行号 19 | 20 | for(int i=0;i> result=new ArrayList<>(); 16 | public List> combine(int n, int k) { 17 | backtrack(new ArrayList(),1,n,k); 18 | return result; 19 | } 20 | 21 | private void backtrack(ArrayList current,int first,int n,int k){ 22 | if(current.size()==k){ 23 | result.add(new ArrayList<>(current)); 24 | return; 25 | } 26 | 27 | for(int i=first;i<=n;i++){ 28 | current.add(i); 29 | backtrack(current,i+1,n,k); 30 | current.remove(current.size()-1); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /demo001-100/demo078.java: -------------------------------------------------------------------------------- 1 | package demo001_100; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * @author:Sun Hongwei 8 | * @2020/2/10 上午12:25 9 | * File Description:子集:给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。 10 | * 11 | * 回朔法(递归) 12 | */ 13 | public class demo078 { 14 | List> results=new ArrayList<>(); 15 | public List> subsets(int[] nums) { 16 | backtrack(nums,new ArrayList(),0); 17 | return results; 18 | } 19 | 20 | //回溯 21 | public void backtrack(int[] nums,ArrayList temp, int start){ 22 | results.add(new ArrayList<>(temp)); 23 | 24 | for(int i=start;i stack=new Stack(); 19 | stack.push(-1); 20 | int maxarea=0; 21 | //压入栈中,遍历 22 | for(int i=0;i=heights[i]){ 24 | maxarea=Math.max(maxarea,heights[stack.pop()]*(i-stack.peek()-1)); 25 | } 26 | stack.push(i); 27 | } 28 | //将栈中剩余元素弹出栈 29 | while (stack.peek()!=-1){ 30 | maxarea=Math.max(maxarea,heights[stack.pop()]* 31 | (heights.length-stack.peek()-1)); 32 | } 33 | return maxarea; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /demo001-100/demo088.java: -------------------------------------------------------------------------------- 1 | /** 2 | * @author:Sun Hongwei 3 | * @2020/2/10 下午3:33 4 | * File Description: 合并两个有序数组:给定两个有序整数数组nums1和nums2, 5 | * 将nums2合并到nums1中,使得num1成为一个有序数组。 6 | * (1) 初始化 nums1 和 nums2 的元素数量分别为 m 和 n。 7 | * (2) 你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。 8 | * 9 | * 解决办法:双指针从后往前遍历:时间O(m+n) 空间O(1) 10 | */ 11 | public class demo088 { 12 | public void merge(int[] nums1, int m, int[] nums2, int n) { 13 | int p1=m-1,p2=n-1,loc=m+n-1; //loc:最后result的长度 14 | while (p1>=0 && p2>=0) { 15 | if(nums1[p1]>nums2[p2]){ 16 | nums1[loc--]=nums1[p1]; 17 | p1--; 18 | }else{ 19 | nums1[loc--]=nums2[p2]; 20 | p2--; 21 | } 22 | } 23 | if(p2>=0){ //如果nums2前面还有剩余,全部移至nums1里面相同位置 24 | for(int i=0;i<=p2;i++){ 25 | nums1[i]=nums2[i]; 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /demo001-100/demo089.java: -------------------------------------------------------------------------------- 1 | package demo001_100; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * @author:Sun Hongwei 8 | * @2020/2/19 下午10:51 9 | * File Description:格雷编码: 格雷编码是一个二进制数字系统,在该系统中, 10 | * 两个连续的数值仅有一个位数的差异。 11 | * 给定一个代表编码总位数的非负整数 n,打印其格雷编码序列。 12 | * 格雷编码序列必须以 0 开头。 13 | * 14 | *镜像法:先统计完k位的所有编码后,将前面最高位填1,将所有数反过来遍历一遍,加起来即为k+1位的编码 15 | */ 16 | public class demo089 { 17 | public List grayCode(int n) { 18 | List result=new ArrayList(); 19 | result.add(0); 20 | int head=1; 21 | for(int i=0;i=0;j--){ 23 | result.add(head+result.get(j)); 24 | } 25 | head=head<<1; 26 | } 27 | return result; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /demo001-100/demo090.java: -------------------------------------------------------------------------------- 1 | package demo001_100; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.List; 6 | 7 | /** 8 | * @author:Sun Hongwei 9 | * @2020/2/14 下午2:15 10 | * File Description:子集 II:给定一个可能包含重复元素的整数数组nums, 11 | * 返回该数组所有可能的子集(幂集)。 12 | * 13 | * 回溯,大致同78题,先排序,遍历时去掉重复的情况 14 | */ 15 | public class demo090 { 16 | List> results=new ArrayList<>(); 17 | public List> subsetsWithDup(int[] nums) { 18 | Arrays.sort(nums); 19 | backtrack(nums,new ArrayList(),0); 20 | return results; 21 | } 22 | //回溯 23 | public void backtrack(int[] nums,ArrayList temp, int start){ 24 | results.add(new ArrayList<>(temp)); 25 | 26 | for(int i=start;istart && nums[i]==nums[i-1]) continue; 29 | 30 | temp.add(nums[i]); 31 | backtrack(nums,temp,i+1); 32 | temp.remove(temp.size()-1); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /demo001-100/demo098.java: -------------------------------------------------------------------------------- 1 | package demo001_100; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/19 下午4:16 6 | * File Description:验证二叉搜索树:给定一个二叉树,判断其是否是一个有效的二叉搜索树。 7 | * 8 | * 假设一个二叉搜索树具有如下特征: 9 | * 1.节点的左子树只包含小于当前节点的数。 10 | * 2.节点的右子树只包含大于当前节点的数。 11 | * 3.所有左子树和右子树自身必须也是二叉搜索树。 12 | * 13 | * 14 | * 递归,注意要有两个形参保存子树的根节点值,保证左子树均小于root的值,右子树均大于root的值 15 | */ 16 | public class demo098 { 17 | public boolean isValid(TreeNode root,Integer low,Integer high){ 18 | if(root==null) return true; 19 | //找出所有不满足的条件 20 | if(low!=null && root.val<=low){ 21 | return false; 22 | } 23 | if(high!=null && root.val>=high){ 24 | return false; 25 | } 26 | if(!isValid(root.left,low,root.val)){ 27 | return false; 28 | } 29 | if(!isValid(root.right,root.val,high)){ 30 | return false; 31 | } 32 | return true; 33 | } 34 | 35 | public boolean isValidBST(TreeNode root) { 36 | return isValid(root,null,null); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /demo001-100/demo100.java: -------------------------------------------------------------------------------- 1 | package demo001_100; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/19 下午11:33 6 | * File Description:相同的树: 给定两个二叉树,编写一个函数来检验它们是否相同。 7 | * 如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。 8 | * 9 | * 10 | * 递归 11 | */ 12 | public class demo100 { 13 | public boolean isSameTree(TreeNode p, TreeNode q) { 14 | if(p==null && q==null) return true; //两个节点均为空 15 | if(p==null || q==null) return false; //两个只有其中一个为空 16 | if(p.val!=q.val) return false; 17 | return isSameTree(p.left,q.left) && isSameTree(p.right,q.right); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /demo101-200/demo101.java: -------------------------------------------------------------------------------- 1 | package demo101_200; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/12 下午3:27 6 | * File Description:对称二叉树:给定一个二叉树,检查它是否是镜像对称的。 7 | * 8 | * 9 | *分别深度遍历左右子树,同样位置的左子树和另一边的右子树进行比较,都相同即可 10 | * 11 | */ 12 | public class demo101 { 13 | //对称二叉树:递归 14 | public static boolean isSymmetric(TreeNode root) { 15 | return isMirror(root,root); 16 | } 17 | 18 | public static boolean isMirror(TreeNode t1, TreeNode t2){ 19 | if(t1==null || t2==null) return t1==t2; 20 | return (t1.val==t2.val) && isMirror(t1.left,t2.right) && isMirror(t2.left,t1.right); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /demo101-200/demo102.java: -------------------------------------------------------------------------------- 1 | package demo101_200; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * @author:Sun Hongwei 8 | * @2020/2/13 下午4:04 9 | * File Description:二叉树的层次遍历:给定一个二叉树,返回其按层次遍历的节点值。 10 | * (即逐层地,从左到右访问所有节点)。 11 | * 12 | * 13 | * 14 | * 深度优先遍历+迭代 15 | */ 16 | public class demo102 { 17 | List> levels=new ArrayList<>(); 18 | 19 | public List> levelOrder(TreeNode root) { 20 | if(root==null) return levels; 21 | helper(root,0); 22 | return levels; 23 | } 24 | 25 | //辅助函数:遍历整个树结构 26 | public void helper(TreeNode root,int level){ 27 | if(levels.size()==level){ 28 | //如果还没有level这个List 29 | levels.add(new ArrayList()); 30 | } 31 | //添加元素 32 | levels.get(level).add(root.val); 33 | if(root.left!=null) helper(root.left,level+1); 34 | if(root.right!=null) helper(root.right,level+1); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /demo101-200/demo104.java: -------------------------------------------------------------------------------- 1 | package demo101_200; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/12 下午3:26 6 | * File Description:二叉树的最大深度:给定一个二叉树,找出其最大深度。 7 | * 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。 8 | * 9 | * 10 | * 深度遍历左右子树即可 11 | */ 12 | public class demo104 { 13 | public int maxDepth(TreeNode root) { 14 | if(root==null) return 0; 15 | return Math.max(maxDepth(root.left),maxDepth(root.right))+1; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /demo101-200/demo108.java: -------------------------------------------------------------------------------- 1 | package demo101_200; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/21 下午12:49 6 | * File Description:将有序数组转换为二叉搜索树: 将一个按照升序排列的有序数组, 7 | * 转换为一棵高度平衡二叉搜索树。(指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。) 8 | * 9 | * 10 | * 升序数组,即为平缓二叉树的中序遍历,不断找出mid作为树的root,递归对树进行遍历即可 11 | */ 12 | public class demo108 { 13 | private int[] nums; 14 | public TreeNode sortedArrayToBST(int[] nums) { 15 | this.nums=nums; 16 | return helper(0,nums.length-1); 17 | } 18 | private TreeNode helper(int left,int right){ 19 | if(left>right){ 20 | return null; 21 | } 22 | int mid=(left+right)/2; 23 | TreeNode root=new TreeNode(nums[mid]); 24 | root.left=helper(left,mid-1); 25 | root.right=helper(mid+1,right); 26 | return root; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /demo101-200/demo110.java: -------------------------------------------------------------------------------- 1 | package demo101_200; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/25 下午10:19 6 | * File Description:平衡二叉树:给定一个二叉树,判断它是否是高度平衡的二叉树。 7 | * 本题中,一棵高度平衡二叉树定义为: 8 | * 一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。 9 | * 10 | * 11 | * 递归 12 | */ 13 | public class demo110 { 14 | public boolean isBalanced(TreeNode root) { 15 | if(root==null){ 16 | return true; 17 | } 18 | if(Math.abs(height(root.left)-height(root.right))>=2) return false; 19 | if(!isBalanced(root.left) || !isBalanced(root.right)) return false; 20 | return true; 21 | } 22 | 23 | private int height(TreeNode root){ 24 | if(root==null){ 25 | return 0; 26 | } 27 | return Math.max(height(root.left),height(root.right))+1; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /demo101-200/demo112.java: -------------------------------------------------------------------------------- 1 | package demo101_200; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * @author:Sun Hongwei 8 | * @2020/2/29 下午5:44 9 | * File Description: 路径总和:给定一个二叉树和一个目标和, 10 | * 判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。 11 | * 12 | * 回溯剪枝,类似113题 13 | */ 14 | public class demo112 { 15 | public boolean hasPathSum(TreeNode root, int sum) { 16 | if(root==null) return false; 17 | sum-=root.val; 18 | if(root.left==null && root.right==null){ 19 | if(sum==0){ 20 | return true; 21 | } 22 | } 23 | return hasPathSum(root.left,sum) || hasPathSum(root.right,sum); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /demo101-200/demo113.java: -------------------------------------------------------------------------------- 1 | package demo101_200; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * @author:Sun Hongwei 8 | * @2020/2/29 下午5:37 9 | * File Description:路径总和 II:给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径。 10 | * 11 | * 回溯+剪枝 12 | */ 13 | public class demo113 { 14 | private List> ans=new ArrayList<>(); 15 | private List temp=new ArrayList<>(); 16 | public List> pathSum(TreeNode root, int sum) { 17 | if(root==null) return ans; 18 | sum-=root.val; 19 | temp.add(root.val); 20 | if(root.left==null && root.right==null){ 21 | if(sum==0){ 22 | ans.add(new ArrayList<>(temp)); 23 | } 24 | } 25 | if(root.left!=null) pathSum(root.left,sum); 26 | if(root.right!=null) pathSum(root.right,sum); 27 | temp.remove(temp.size()-1); 28 | return ans; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /demo101-200/demo118.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.List; 3 | 4 | /** 5 | * @author:Sun Hongwei 6 | * @2020/2/9 下午11:57 7 | * File Description:杨辉三角:给定一个非负整数 numRows,生成杨辉三角的前 numRows 行。 8 | * 9 | * 动态规划 10 | */ 11 | public class demo118 { 12 | public List> generate(int numRows) { 13 | List> triangle=new ArrayList>(); 14 | if(numRows==0) return triangle; 15 | 16 | //第一行 17 | triangle.add(new ArrayList<>()); 18 | triangle.get(0).add(1); 19 | 20 | //下面开始动态规划: 21 | for(int i=1;i row=new ArrayList(); 23 | List previous=triangle.get(i-1); //前一行 24 | 25 | row.add(1); //每行第一个 26 | for(int j=1;jp){ 18 | minprice=p; //若当前价格是最小,更新minprice 19 | }else if(p-minprice>maxprofit){ 20 | maxprofit=p-minprice; //若当前价格不是最小,判断是否需要更新maxprofit 21 | } 22 | } 23 | return maxprofit; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /demo101-200/demo122.java: -------------------------------------------------------------------------------- 1 | /** 2 | * @author:Sun Hongwei 3 | * @2020/2/11 下午7:41 4 | * File Description:买卖股票的最佳时机II 5 | * 6 | * 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。 7 | * 设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。 8 | * 9 | * 10 | * 尽可能的多赚钱,就是只要后一天比前一天多,那么就进行一次买卖 11 | * 12 | */ 13 | public class demo122 { 14 | public int maxProfit(int[] prices) { 15 | int maxprofit=0; 16 | for(int i=1;iprices[i-1]){ 18 | maxprofit+=(prices[i]-prices[i-1]); 19 | } 20 | } 21 | return maxprofit; 22 | 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /demo101-200/demo125.java: -------------------------------------------------------------------------------- 1 | /** 2 | * @author:Sun Hongwei 3 | * @2020/2/9 下午10:28 4 | * File Description:验证回文串:给定一个字符串,验证它是否是回文串, 5 | * 只考虑字母和数字字符,可以忽略字母的大小写。 6 | * 双指针:一个从前往后,一个从后往前 7 | */ 8 | public class demo125 { 9 | public boolean isPalindrome(String s) { 10 | int l=0,r=s.length()-1; 11 | while (l visited=new HashSet(); 21 | while(head!=null){ 22 | if(visited.contains(head)){ 23 | return head; 24 | } 25 | visited.add(head); 26 | head=head.next; 27 | } 28 | return null; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /demo101-200/demo151.java: -------------------------------------------------------------------------------- 1 | package demo101_200; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/25 下午8:11 6 | * File Description:翻转字符串里的单词: 给定一个字符串,逐个翻转字符串中的每个单词。 7 | * 8 | * 用split(" ")分割单词 9 | */ 10 | public class demo151 { 11 | public String reverseWords(String s) { 12 | String[] ss=s.trim().split(" "); 13 | StringBuilder stringBuilder=new StringBuilder(); 14 | for(int i=ss.length-1;i>=0;i--){ 15 | if(!ss[i].isEmpty()){ //防止原字符串空了两格 16 | stringBuilder.append(ss[i]); 17 | if (i != 0) { 18 | stringBuilder.append(" "); 19 | } 20 | } 21 | } 22 | return stringBuilder.toString(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /demo101-200/demo152.java: -------------------------------------------------------------------------------- 1 | package demo101_200; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/14 下午10:39 6 | * File Description:乘积最大子序列:给定一个整数数组 nums , 7 | * 找出一个序列中乘积最大的连续子序列(该序列至少包含一个数)。 8 | * 9 | * 10 | * 动态规划:d(p)=max(d(max)(p-1)*nums[p],nums[p]) 11 | * 并且考虑负数情况 d(p)=max(d(min)(p-1)*nums[p],nums[p]) 12 | * 13 | * 始终储存两个常量,最大值和最小值 14 | * 15 | */ 16 | public class demo152 { 17 | public int maxProduct(int[] nums) { 18 | int maxnum=Integer.MIN_VALUE; 19 | int imax=1,imin=1,temp; 20 | for(int i=0;inums[right]){ //右半边无序,最小数在右边 21 | left=mid+1; 22 | } 23 | } 24 | return nums[left]; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /demo101-200/demo154.java: -------------------------------------------------------------------------------- 1 | package demo101_200; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/28 下午6:42 6 | * File Description:寻找旋转排序数组中的最小值 II::假设按照升序排序的数组在预先未知 7 | * 的某个点上进行了旋转。( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。 8 | * 请找出其中最小的元素。注意数组中可能存在重复的元素。 9 | * 10 | * 二分查找,用nums[right]和nums[mid]进行比较,判断哪半边是有序的,进而找出最小值 11 | * 12 | */ 13 | public class demo154 { 14 | public int findMin(int[] nums) { 15 | int left=0,right=nums.length-1,mid; 16 | while(leftnums[right]){ //右半边无序,最小数在右边 21 | left=mid+1; 22 | }else{ //遇到有重复的情况 23 | right=right-1; //right向左移一位继续比较 24 | } 25 | } 26 | return nums[left]; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /demo101-200/demo160.java: -------------------------------------------------------------------------------- 1 | /** 2 | * @author:Sun Hongwei 3 | * @2020/2/9 下午9:39 4 | * File Description:编写一个程序,找到两个单链表相交的起始节点 5 | *双指针法:两个指针分别走完a和b后,换个链表走,第一次相遇的节点就是公共节点 6 | */ 7 | public class demo160 { 8 | public ListNode getIntersectionNode(ListNode headA, ListNode headB) { 9 | if(headA==null || headB==null) return null; 10 | ListNode pa=headA; 11 | ListNode pb=headB; 12 | while (pa!=pb){ //当一个链表走完后,走另一个链表 13 | pa=(pa==null)?headB:pa.next; 14 | pb=(pb==null)?headA:pb.next; 15 | 16 | } 17 | return pa; 18 | 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /demo101-200/demo162.java: -------------------------------------------------------------------------------- 1 | package demo101_200; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/19 下午9:16 6 | * File Description:寻找峰值:峰值元素是指其值大于左右相邻值的元素。 7 | * 给定一个输入数组 nums,其中 nums[i] ≠ nums[i+1],找到峰值元素并返回其索引。 8 | * 用O(logN) 时间复杂度 9 | * 10 | * 11 | * 二分查找+递归 12 | */ 13 | public class demo162 { 14 | public int findPeakElement(int[] nums) { 15 | return search(nums,0,nums.length-1); 16 | } 17 | public int search(int[] nums,int left,int right){ 18 | if(left==right) return left; 19 | int mid=(left+right)/2; 20 | if(nums[mid]>nums[mid+1]){ //mid可能存在于一个局部单减的区间,先去左半区间找 21 | return search(nums,left,mid); 22 | } 23 | return search(nums,mid+1,right); 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /demo101-200/demo169.java: -------------------------------------------------------------------------------- 1 | package demo101_200; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/12 下午3:03 6 | * File Description:多数元素:给定一个大小为 n 的数组,找到其中的多数元素。 7 | * 多数元素是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。 8 | * 可以假设数组是非空的,并且给定的数组总是存在多数元素。 9 | * 10 | * 11 | * 往后遍历,假定某个数是answer,如果出现+1,否则-1,如果到某个地方>=0时更新 多数元素 12 | */ 13 | public class demo169 { 14 | public static int majorityElement(int[] nums) { 15 | int count=0; 16 | Integer x=null; 17 | for(int num:nums){ 18 | if(count==0) x=num; //换个数 19 | count+=(num==x)?1:-1; 20 | } 21 | return x; 22 | } 23 | 24 | 25 | public static void main(String[] args) { 26 | int[] x=new int[]{2,2,1,1,1,2,2}; 27 | int result=majorityElement(x); 28 | System.out.println(result); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /demo101-200/demo171.java: -------------------------------------------------------------------------------- 1 | package demo101_200; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/12 下午3:01 6 | * File Description:Excel表列序号:给定一个Excel表格中的列名称,返回其相应的列序号。 7 | * 8 | * 相当于26进制 9 | * 10 | */ 11 | public class demo171 { 12 | public static int titleToNumber(String s) { 13 | int result=0; 14 | for(int i=0;i=1){ 12 | count+=n/5; //分别统计含有多少5,25,125... 13 | n=n/5; 14 | } 15 | return count; 16 | } 17 | public static void main(String[] args) { 18 | System.out.println(trailingZeroes(5)); 19 | System.out.println(trailingZeroes(25)); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /demo101-200/demo189.java: -------------------------------------------------------------------------------- 1 | package demo101_200; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/12 下午10:29 6 | * File Description:旋转数组: 给定一个数组,将数组中的元素向右移动k个位置,其中k是非负数。 7 | * 8 | * 9 | * 反转三次即可:1. 从第1~n-k个数反转 10 | * 2. 从第(n-k+1)~n个数反转 11 | * 3. 从第1~n个数反转 12 | */ 13 | public class demo189 { 14 | public static void rotate(int[] nums, int k) { 15 | k=k%nums.length; //防止k比nums.length要大 16 | reverse(nums,0,nums.length-k-1); 17 | reverse(nums,nums.length-k,nums.length-1); 18 | reverse(nums,0,nums.length-1); 19 | } 20 | 21 | public static void reverse(int[] nums,int start,int end){ 22 | while(start0){ 11 | if((n & 1)!=0){ //和1进行&运算,如果不是0,说明尾数(个位数)是1 12 | bits++; 13 | } 14 | n=n>>>1; //右移一位(>>>:无符号数右移,负数高位补0,>>:负数高位补1) 15 | } 16 | return bits; 17 | } 18 | public static void main(String[] args) { 19 | int n = 00000000000000000000000010000000; 20 | System.out.println(hammingWeight(n)); 21 | } 22 | 23 | 24 | } 25 | -------------------------------------------------------------------------------- /demo101-200/demo198.java: -------------------------------------------------------------------------------- 1 | package demo101_200; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/12 下午3:10 6 | * File Description:打家劫舍:从数组中选取不相邻的数,问能取到的最大值 7 | * 8 | * 动态规划: 9 | * 转移公式:f(k) = max(f(k – 2) + A(k),f(k – 1)) 10 | */ 11 | public class demo198 { 12 | public static int rob(int[] nums){ 13 | if(nums.length<1) return 0; 14 | if(nums.length==1) return nums[0]; 15 | int[] maxsum=new int[nums.length]; 16 | maxsum[0]=nums[0]; 17 | maxsum[1]=Math.max(nums[0],nums[1]); 18 | for(int i=2;i=grid.length || j<0 || j>=grid[0].length ) return; 32 | if(grid[i][j]=='0') return; 33 | grid[i][j]='0'; 34 | dfs(i-1,j); 35 | dfs(i+1,j); 36 | dfs(i,j-1); 37 | dfs(i,j+1); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /demo201-300/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/demo201-300/.DS_Store -------------------------------------------------------------------------------- /demo201-300/demo202.java: -------------------------------------------------------------------------------- 1 | package demo201_300; 2 | 3 | import java.util.HashSet; 4 | 5 | /** 6 | * @author:Sun Hongwei 7 | * @2020/2/12 下午3:52 8 | * File Description:快乐数:一个“快乐数”定义为:对于一个正整数,每一次将该数替换为 9 | * 它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1, 10 | * 也可能是无限循环但始终变不到 1。如果可以变为 1,那么这个数就是快乐数。 11 | * 12 | * 13 | * hashset的方法,防止循环的现象发生,剩下的依次计算即可。 14 | */ 15 | public class demo202 { 16 | public static boolean isHappy(int n) { 17 | HashSet set=new HashSet(); 18 | set.add(n); 19 | while(n!=1){ 20 | n=PowerSum(n); 21 | if(set.contains(n)) return false; 22 | else set.add(n); 23 | } 24 | return true; 25 | } 26 | 27 | public static int PowerSum(int x){ 28 | int sum=0; 29 | while(x!=0){ 30 | sum+=(x%10)*(x%10); 31 | x/=10; 32 | } 33 | return sum; 34 | } 35 | 36 | public static void main(String[] args) { 37 | int n=19; 38 | System.out.println(isHappy(n)); 39 | } 40 | } -------------------------------------------------------------------------------- /demo201-300/demo204.java: -------------------------------------------------------------------------------- 1 | import java.util.HashSet; 2 | import java.util.Set; 3 | 4 | /** 5 | * @author:Sun Hongwei 6 | * @2020/2/10 下午3:16 7 | * File Description:计数质数:统计所有小于非负整数 n 的质数的数量。 8 | * hash表:依次划去2,3,5,7,11。。。的倍数 9 | */ 10 | public class demo204 { 11 | public static int countPrimes(int n) { 12 | int count=0; 13 | int[] nums=new int[n]; 14 | for(int i=2;i p=new PriorityQueue(); 20 | 21 | //遍历数组放入堆中: 22 | for(int n:nums){ 23 | p.add(n); 24 | if(p.size()>k){ //如果堆的容量大于k时 25 | p.poll(); //每次从堆顶移除最小值 26 | } 27 | } 28 | return p.poll(); 29 | 30 | } 31 | 32 | public static void main(String args[]){ 33 | int[] nums=new int[]{2,3,6,8,4,1}; 34 | int k=2; 35 | int x=findKthLargest(nums,k); 36 | System.out.println(x); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /demo201-300/demo217.java: -------------------------------------------------------------------------------- 1 | import java.util.HashSet; 2 | import java.util.Set; 3 | 4 | /** 5 | * @author:Sun Hongwei 6 | * @2020/2/10 上午1:09 7 | * File Description:存在重复元素:给定一个整数数组,判断是否存在重复元素。 8 | * 9 | * hash表 10 | */ 11 | public class demo217 { 12 | public boolean containsDuplicate(int[] nums) { 13 | Set set=new HashSet(nums.length); 14 | for(int n:nums){ 15 | if(set.contains(n)) return true; 16 | set.add(n); 17 | } 18 | return false; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /demo201-300/demo219.java: -------------------------------------------------------------------------------- 1 | import java.util.HashSet; 2 | import java.util.Set; 3 | 4 | /** 5 | * @author:Sun Hongwei 6 | * @2020/2/10 下午1:42 7 | * File Description:存在重复元素 II:给定一个整数数组和一个整数 k,判断数组中是否存在两个不同的索引 i 和 j,使得 nums [i] = nums [j],并且 i 和 j 的差的绝对值最大为 k。 8 | * 9 | *改进版hashset: 设置一个大小为k的hashset,如果满了的话删除第n-k个元素 10 | * 11 | */ 12 | public class demo219 { 13 | public boolean containsNearbyDuplicate(int[] nums, int k) { 14 | if(k<=0) return false; 15 | Set set=new HashSet(k); 16 | for(int n=0;n inorder(TreeNode root,ArrayList array){ 12 | //每次代入数组,防止递归时产生的问题 13 | if(root==null) return array; 14 | inorder(root.left,array); 15 | array.add(root.val); 16 | inorder(root.right,array); 17 | return array; 18 | } 19 | 20 | 21 | public int kthSmallest(TreeNode root, int k){ 22 | ArrayList arrayList=inorder(root,new ArrayList()); 23 | return arrayList.get(k-1); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /demo201-300/demo231.java: -------------------------------------------------------------------------------- 1 | /** 2 | * @author:Sun Hongwei 3 | * @2020/2/10 上午12:35 4 | * File Description:2的幂:给定一个整数,编写一个函数来判断它是否是 2 的幂次方。 5 | * 6 | * 位运算! x & (x-1): 7 | * (1)如果x是2的幂,那么二进制为100000 ,结果为0 8 | * (2)如果x不是2的幂,那么最高位一定还是1 9 | */ 10 | public class demo231 { 11 | public boolean isPowerOfTwo(int n) { 12 | if(n<=0) return false; 13 | return (n & (n-1))==0; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /demo201-300/demo233.java: -------------------------------------------------------------------------------- 1 | package demo201_300; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/29 下午4:50 6 | * File Description:数字 1 的个数: 给定一个整数n,计算所有小于等于n的非负整数中数字1出现的个数。 7 | * 8 | * 分别计算个,十,百,。。。上1的个数 9 | * 计算每一位上的1个数方法,分为两部分(以12345的百位为例): 10 | * (1) 先求除1000的商,表示有多少个1000(百位上1的个数以1000作为一次循环),并乘上100,代表1-12000中百位上1的个数 11 | * (2) 求12001-12345中1的个数,取1000的模,减去100,再加1,此时这个数若超过100,则计入统计(统计12100-12199间的数),否则不计入 12 | * 13 | */ 14 | public class demo233 { 15 | public int countDigitOne(int n) { 16 | long num=n; 17 | long count=0; 18 | for(long i=1;i<=num;i*=10){ 19 | count+=(num/(i*10))*i+Math.min(Math.max(num%(i*10)-i+1,0),i); 20 | } 21 | return (int)count; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /demo201-300/demo235.java: -------------------------------------------------------------------------------- 1 | package demo201_300; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/13 上午1:51 6 | * File Description: 二叉搜索树的最近公共祖先: 7 | * 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。 8 | * 9 | * 10 | * 递归 11 | * 二叉搜索树root的值比左子树都要大,比右子树都要小,所以根据p,q,和root值的大小关系就能确定递归方向 12 | */ 13 | public class demo235 { 14 | public TreeNode lowestCommonAncestor(TreeNode root,TreeNode p,TreeNode q) { 15 | if (root.val>p.val && root.val>q.val){ 16 | return lowestCommonAncestor(root.left,p,q); 17 | }else if(root.val=0){ 18 | if(matrix[m][n]==target){ 19 | return true; 20 | }else if(matrix[m][n]>target){ //大于target,往左移1格 21 | n--; 22 | }else{ //小于target,往下移1格 23 | m++; 24 | } 25 | } 26 | return false; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /demo201-300/demo242.java: -------------------------------------------------------------------------------- 1 | import com.sun.tools.javac.util.Name; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/9 下午9:28 6 | * File Description:给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。 7 | * (除了字母顺序不同,其他都一样) 8 | * 方法:hash表 9 | */ 10 | public class demo242 { 11 | public static boolean isAnagram(String s, String t) { 12 | if(s.length()!=t.length()) return false; 13 | int[] alpha=new int[26]; 14 | for(char i:s.toCharArray()){ //遍历第一个数组,把每个字母出现的地方+1 15 | alpha[i-'a']++; 16 | } 17 | for(char j:t.toCharArray()){ 18 | alpha[j-'a']--; //遍历第二个数组,把每个字母出现的地方-1 19 | if(alpha[j-'a']<0) return false; //如果某个位置小于0,提前结束,返回错误 20 | } 21 | return true; 22 | } 23 | public static void main(String[] args) { 24 | String s="anagram"; 25 | String t="nagaram"; 26 | System.out.println(isAnagram(s,t)); 27 | 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /demo201-300/demo263.java: -------------------------------------------------------------------------------- 1 | package demo201_300; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/14 下午11:20 6 | * File Description:丑数: 编写一个程序判断给定的数是否为丑数。 7 | * 丑数就是只包含质因数 2, 3, 5 的正整数。 8 | * 9 | * 直接除到1为止 10 | */ 11 | public class demo263 { 12 | public boolean isUgly(int num) { 13 | if(num<1) return false; 14 | while (num!=1){ 15 | if(num%2!=0 && num%3!=0 && num%5!=0){ 16 | return false; 17 | }else if(num%2==0){ 18 | num/=2; 19 | }else if(num%3==0){ 20 | num/=3; 21 | }else{ 22 | num/=5; 23 | } 24 | } 25 | return true; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /demo201-300/demo264.java: -------------------------------------------------------------------------------- 1 | package demo201_300; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/26 上午12:21 6 | * File Description:丑数 II:编写一个程序,找出第 n 个丑数。 7 | * 丑数就是只包含质因数 2, 3, 5 的正整数。 8 | * 9 | * 10 | *用三个指针,进行动态规划,分别比较指针所指的数的2,3,5倍,找出最小的数放入数组后,再更新 11 | */ 12 | public class demo264 { 13 | public int nthUglyNumber(int n) { 14 | int[] dp = new int[n]; 15 | dp[0]=1; 16 | int a2=0,a3=0,a5=0,min; 17 | for(int i=1;i=j){ 25 | j++; 26 | } 27 | } 28 | } 29 | } 30 | 31 | public static void main(String[] args) { 32 | int result=0; 33 | int num[]=new int[]{0,1,0,3,12}; 34 | moveZeroes(num); 35 | } 36 | } 37 | 38 | -------------------------------------------------------------------------------- /demo201-300/demo287.java: -------------------------------------------------------------------------------- 1 | package demo201_300; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/10 下午2:57 6 | * File Description:寻找重复数:给定一个包含 n + 1 个整数的数组 nums, 7 | * 其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。 8 | * 假设只有一个重复的整数,找出这个重复的数。 9 | * 10 | * 双指针(快慢指针)key->value->key在有重复整数的数组里必然存在一个循环 11 | * 12 | */ 13 | public class demo287 { 14 | 15 | public int findDuplicate(int[] nums) { 16 | if(nums.length<=1) return -1; 17 | int slow=nums[0],fast=nums[0]; //定义快慢指针 18 | do{ //分别设置两个快慢指针,直到两者相遇 19 | slow=nums[slow]; 20 | fast=nums[nums[fast]]; 21 | }while(slow!=fast); 22 | 23 | //再从头开始设置一个指针,与重复的指针值相等时,则返回那个重复的数 24 | slow=nums[0]; 25 | while(slow!=fast){ 26 | slow=nums[slow]; 27 | fast=nums[fast]; 28 | } 29 | return slow; 30 | 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /demo201-300/demo292.java: -------------------------------------------------------------------------------- 1 | package demo201_300; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/13 上午1:45 6 | * File Description:Nim 游戏:你和你的朋友,两个人一起玩 Nim 游戏:桌子上有一堆石头, 7 | * 每次你们轮流拿掉 1 - 3 块石头。 拿掉最后一块石头的人就是获胜者。你作为先手。 8 | * 编写一个函数,来判断你是否可以在给定石头数量的情况下赢得游戏。 9 | * 10 | * 11 | *每个回合两人之和可以始终为4的倍数(1/3,2/2,3/1),所以只要不是4的倍数,自己就可以摸完后变成后手 12 | */ 13 | public class demo292 { 14 | public boolean canWinNim(int n) { 15 | return n%4!=0; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /demo201-300/demo300.java: -------------------------------------------------------------------------------- 1 | package demo201_300; 2 | 3 | import java.lang.reflect.Array; 4 | import java.util.Arrays; 5 | 6 | /** 7 | * @author:Sun Hongwei 8 | * @2020/2/16 下午10:13 9 | * File Description:最长上升子序列:给定一个无序的整数数组,找到其中最长上升子序列的长度。 10 | * 11 | * 12 | * 动态规划:状态转移方程 13 | */ 14 | public class demo300 { 15 | public int lengthOfLIS(int[] nums) { 16 | if(nums.length==0) return 0; 17 | int result=0; 18 | int[] dp=new int[nums.length]; 19 | Arrays.fill(dp,1); 20 | for(int i=0;i1){ 14 | if(n%3!=0){ 15 | return false; 16 | } 17 | n/=3; 18 | } 19 | return true; 20 | } 21 | 22 | public static void main(String[] args) { 23 | int x=27; 24 | boolean result=isPowerOfThree(x); 25 | System.out.println(result); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /demo301-400/demo328.java: -------------------------------------------------------------------------------- 1 | /** 2 | * @author:Sun Hongwei 3 | * @2020/2/9 下午9:00 4 | * File Description:奇偶链表:给定一个单链表,把所有的奇数节点和偶数节点分别排在一起 5 | * (链表内部点的细节移动) 6 | */ 7 | public class demo328 { 8 | public static ListNode oddEvenList(ListNode head) { 9 | if(head==null) return null; 10 | ListNode odd=head; //奇数节点 11 | ListNode even=head.next; //偶数节点 12 | ListNode even_head=even; //偶数节点链表第一个 13 | while (even!=null && even.next!=null){ 14 | odd.next=even.next; 15 | even.next=even.next.next; 16 | //两个数组分别向后遍历 17 | odd=odd.next; 18 | even=even.next; 19 | } 20 | odd.next=even_head; 21 | return head; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /demo301-400/demo338.java: -------------------------------------------------------------------------------- 1 | package demo301_400; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/14 下午9:48 6 | * File Description:比特位计数:给定一个非负整数 num。 7 | * 对于 0 ≤ i ≤ num 范围中的每个数字 i ,计算其二进制数中的 1 的数目并将它们作为数组返回。 8 | * 9 | * 10 | * 位计算 + 动态规划: 11 | * f(x)=f(x/2)+(x mod 2) 12 | * 13 | */ 14 | public class demo338 { 15 | public int[] countBits(int num) { 16 | int[] res=new int[num+1]; 17 | for(int i=1;i<=num;i++){ 18 | res[i]=res[i>>1]+(i & 1); 19 | //a & 1:判断末位数字是0或1 20 | } 21 | return res; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /demo301-400/demo342.java: -------------------------------------------------------------------------------- 1 | /** 2 | * @author:Sun Hongwei 3 | * @2020/2/10 上午12:42 4 | * File Description:4的幂:给定一个整数,编写一个函数来判断它是否是 4 的幂次方。 5 | * 6 | * 位运算!(1) x & (x-1):先保证是2的幂 7 | * (2)4的幂和(101010...1010)进行与计算^:结果一定是0,并且是2的幂而不是4的幂的数结果一定不为0 8 | */ 9 | public class demo342 { 10 | public static boolean isPowerOfFour(int num) { 11 | System.out.println(((num^(num-1)))); 12 | return (num>0) && ((num&(num-1))==0) && ((num&0xaaaaaaaa)==0); 13 | } 14 | public static void main(String[] args) { 15 | int n=16; 16 | System.out.println(isPowerOfFour(n)); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /demo301-400/demo343.java: -------------------------------------------------------------------------------- 1 | package demo301_400; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/27 下午11:00 6 | * File Description:整数拆分:给定一个正整数 n,将其拆分为至少两个正整数的和, 7 | * 并使这些整数的乘积最大化。 返回你可以获得的最大乘积。 8 | * 9 | * 1.若n<4时,单独考虑 10 | * 2.若n>4,尽可能多拆成3 11 | * (1) 若正好是3的倍数,结束 12 | * (2) 若余数还剩1的话,1+3=2+2,换成两个2 13 | * (3) 若余数还剩2的话,直接再乘2 14 | * 15 | */ 16 | public class demo343 { 17 | public int integerBreak(int n) { 18 | int ans=n-1,count=n/3; 19 | if(n<=3) return ans; //2和3的时候单独考虑 20 | if(n%3==0){ 21 | ans=(int)Math.pow(3,count); 22 | }else if(n%3==1){ 23 | ans=(int)Math.pow(3,count-1)*4; 24 | }else{ 25 | ans=(int)Math.pow(3,count)*2; 26 | } 27 | return ans; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /demo301-400/demo344.java: -------------------------------------------------------------------------------- 1 | package demo301_400; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/12 下午3:33 6 | * File Description:反转字符串: 将输入的字符串反转过来, 7 | * 必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。 8 | * 9 | * 额外设置个变量temp,前后交换即可 10 | */ 11 | public class demo344 { 12 | public static void reverseString(char[] s) { 13 | char temp='a'; 14 | for(int i=0;i "); 21 | } 22 | 23 | } 24 | 25 | public static void main(String[] args) { 26 | char[] x=new char[]{'h','e','l','l','o'}; 27 | reverseString(x); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /demo301-400/demo347.java: -------------------------------------------------------------------------------- 1 | package demo301_400; 2 | 3 | import java.util.*; 4 | 5 | /** 6 | * @author:Sun Hongwei 7 | * @2020/2/12 下午8:36 8 | * File Description:前 K 个高频元素:给定一个非空的整数数组,返回其中出现频率前 k 高的元素。 9 | * 10 | * 用一个hashmap统计个数 11 | * 并建立一个PriorityQueue用堆来筛选前k个元素 12 | */ 13 | public class demo347 { 14 | public List topKFrequent(int[] nums, int k) { 15 | Map map=new HashMap(); //存储个数 16 | for(int n:nums){ 17 | //map.getOrDefault(x1,x2):默认取x1的值,若为空取x2 18 | map.put(n,map.getOrDefault(n,0)+1); 19 | } 20 | 21 | PriorityQueue heap=new PriorityQueue 22 | ((n1,n2) ->map.get(n1)-map.get(n2)); //按照value值从小到大建堆 23 | 24 | for(int n:map.keySet()){ 25 | heap.add(n); 26 | if(heap.size()>k){ 27 | heap.poll(); 28 | } 29 | } 30 | 31 | List ktop=new ArrayList(); 32 | while (!heap.isEmpty()){ 33 | ktop.add(heap.poll()); //把堆中元素防止arraylist中 34 | } 35 | Collections.reverse(ktop); //数组翻转 36 | return ktop; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /demo301-400/demo349.java: -------------------------------------------------------------------------------- 1 | import java.lang.reflect.Array; 2 | import java.util.Arrays; 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | /** 7 | * @author:Sun Hongwei 8 | * @2020/2/11 下午7:08 9 | * File Description:两个数组的交集: 输出结果中的每个元素一定是唯一的。 10 | * 11 | * 12 | * hash表 13 | */ 14 | public class demo349 { 15 | public int[] intersection(int[] nums1, int[] nums2) { 16 | Set set1=new HashSet(); //Set1存放nums1的值 17 | for(int n:nums1){ 18 | set1.add(n); 19 | } 20 | 21 | Set set2=new HashSet(); //Set2存放nums2和nums1的交集 22 | for(int n:nums2){ 23 | if(set1.contains(n)){ 24 | set2.add(n); 25 | } 26 | } 27 | 28 | int[] res=new int[set2.size()]; //Set结果移至数组中 29 | int k=0; 30 | for(int s:set2){ 31 | res[k++]=s; 32 | } 33 | return res; 34 | 35 | } 36 | } 37 | 38 | -------------------------------------------------------------------------------- /demo301-400/demo350.java: -------------------------------------------------------------------------------- 1 | import java.lang.reflect.Array; 2 | import java.util.*; 3 | 4 | /** 5 | * @author:Sun Hongwei 6 | * @2020/2/11 下午6:46 7 | * File Description:两个数组的交集 II: 给定两个数组,编写一个函数来计算它们的交集。 8 | * 9 | * 1.输出结果中每个元素出现的次数,应与元素在两个数组中出现的次数一致。 10 | * 2.我们可以不考虑输出结果的顺序。 11 | * 12 | * 先排序,再用两个指针依次遍历 13 | */ 14 | public class demo350 { 15 | public int[] intersect(int[] nums1, int[] nums2) { 16 | //先排序 17 | Arrays.sort(nums1); 18 | Arrays.sort(nums2); 19 | int[] res=new int[Math.min(nums1.length,nums2.length)]; 20 | int l1=0,l2=0,k=0; 21 | //依次往后遍历,遇到相同的数加进res中 22 | while(l1nums2[l2]){ 26 | l2++; 27 | }else{ 28 | res[k++]=nums1[l1]; 29 | l1++;l2++; 30 | } 31 | } 32 | return Arrays.copyOf(res,k); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /demo301-400/demo371.java: -------------------------------------------------------------------------------- 1 | package demo301_400; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/19 下午9:27 6 | * File Description:两整数之和:不使用运算符 + 和 - ​​​​​​​,计算两整数 ​​​​​​​a 、b ​​​​​​​之和。 7 | * 8 | * 9 | * 位运算(二进制) 10 | * 1.各位相加,不考虑进位:异或操作(^) 11 | * 2.计算进位值,进行与操作(&),再左移一位(<<) 12 | * 3.重复上述步骤,当一个数为0时,另一个数即为最终答案 13 | * 14 | * a:不考虑进位的和 b:进位值 这两个数相加既可以看成原先两数相加之和,又可以看成新的两部分之和, 15 | * 总之在这个过程中a+b的总和一定不变,所以当一个数为0时,另一个即为最终答案 16 | */ 17 | public class demo371 { 18 | public int getSum(int a, int b) { 19 | int temp; 20 | while (b!=0){ 21 | temp=a^b; 22 | b=(a&b)<<1; 23 | a=temp; 24 | } 25 | return a; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /demo301-400/demo378.java: -------------------------------------------------------------------------------- 1 | package demo301_400; 2 | 3 | import java.util.Comparator; 4 | import java.util.PriorityQueue; 5 | import java.util.Queue; 6 | 7 | /** 8 | * @author:Sun Hongwei 9 | * @2020/2/15 下午1:17 10 | * File Description:有序矩阵中第K小的元素: 给定一个 n x n 矩阵, 11 | * 其中每行和每列元素均按升序排序,找到矩阵中第k小的元素。 12 | * 13 | * 用优先队列PriorityQueue实现最大堆(容量为k),最后返回堆顶值。 14 | */ 15 | public class demo378{ 16 | public int kthSmallest(int[][] matrix, int k) { 17 | PriorityQueue p=new PriorityQueue(new Comparator() { 18 | @Override 19 | public int compare(Integer p1, Integer p2) { 20 | return p2-p1; //最大堆 21 | } 22 | }); 23 | for(int i=0;ik) p.poll(); //当堆元素超过k个元素,去掉当前最大值 27 | } 28 | } 29 | return p.poll(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /demo301-400/demo387.java: -------------------------------------------------------------------------------- 1 | /** 2 | * @author:Sun Hongwei 3 | * @2020/2/11 下午5:40 4 | * File Description:字符串中的第一个唯一字符:给定一个字符串,找到它的第一个不重复的字符, 5 | * 并返回它的索引。如果不存在,则返回 -1。 6 | * 7 | * 方法:Hash表遍历一遍统计数目 8 | */ 9 | public class demo387 { 10 | public int firstUniqChar(String s) { 11 | int[] schar=new int[26]; 12 | for(char c:s.toCharArray()){ 13 | schar[c-'a']++; 14 | } 15 | for(int num=0;num fizzBuzz(int n) { 18 | List res=new ArrayList<>(n); 19 | for(int x=1;x<=n;x++){ 20 | if(x%3==0 && x%5==0){ 21 | res.add("FizzBuzz"); 22 | }else if(x%3==0){ 23 | res.add("Fizz"); 24 | }else if(x%5==0){ 25 | res.add("Buzz"); 26 | }else{ 27 | res.add(Integer.toString(x)); 28 | } 29 | } 30 | return res; 31 | 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /demo401-500/demo448.java: -------------------------------------------------------------------------------- 1 | package demo401_500; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * @author:Sun Hongwei 8 | * @2020/2/16 下午10:41 9 | * File Description:找到所有数组中消失的数字: 给定一个范围在1 ≤ a[i] ≤ n ( n = 数组大小 ) 10 | * 的整型数组,数组中的元素一些出现了两次,另一些只出现一次。 11 | * 找到所有在 [1, n] 范围之间没有出现在数组中的数字。 12 | * 13 | * 14 | * 15 | * hash方法:设置一个数组统计出现次数,在遍历一遍找到个数是0的地方 16 | */ 17 | public class demo448 { 18 | public List findDisappearedNumbers(int[] nums) { 19 | int[] count=new int[nums.length+1]; 20 | for(int n:nums){ 21 | count[n]++; 22 | } 23 | 24 | List result=new ArrayList(); 25 | for (int i=1;i>1; //向右移1位 29 | } 30 | return count; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /demo401-500/demo485.java: -------------------------------------------------------------------------------- 1 | package demo401_500; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/24 下午4:52 6 | * File Description:最大连续1的个数:给定一个二进制数组, 计算其中最大连续1的个数。 7 | * 8 | * 9 | * 遍历统计即可 10 | */ 11 | public class demo485 { 12 | public int findMaxConsecutiveOnes(int[] nums) { 13 | int max=0,count=0; 14 | for (int n:nums){ 15 | if(n==1){ 16 | count++; 17 | if(count>max){ 18 | max=count; 19 | } 20 | }else{ 21 | count=0; 22 | } 23 | } 24 | return max; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /demo501-600/demo509.java: -------------------------------------------------------------------------------- 1 | package demo501_600; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/27 下午10:41 6 | * File Description:斐波那契数: 斐波那契数,通常用 F(n) 表示,形成的序列称为斐波那契数列。 7 | * 该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。 8 | * 9 | * 用递归的话可以解决,但时间复杂度过高,直接用三数互相替代,累加节约时间 10 | */ 11 | public class demo509 { 12 | public int fib(int N) { 13 | if(N==0) return 0; 14 | if(N==1) return 1; 15 | int a1=0,a2=1,a=1; 16 | for(int i=2;i<=N;i++){ 17 | a=a1+a2; 18 | a1=a2; 19 | a2=a; 20 | } 21 | return a; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /demo501-600/demo520.java: -------------------------------------------------------------------------------- 1 | package demo501_600; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/24 下午4:43 6 | * File Description:检测大写字母:给定一个单词,你需要判断单词的大写使用是否正确。 7 | * 8 | * 我们定义,在以下情况时,单词的大写用法是正确的: 9 | * 10 | * 1.全部字母都是大写,比如"USA"。 11 | * 2.单词中所有字母都不是大写,比如"leetcode"。 12 | * 3.如果单词不只含有一个字母,只有首字母大写, 比如 "Google"。 13 | * 否则,我们定义这个单词没有正确使用大写字母。 14 | * 15 | */ 16 | public class demo520 { 17 | public boolean detectCapitalUse(String word) { 18 | int count=0; 19 | int index=0; 20 | if(word.length()==1) return true; 21 | for(int i=0;i set=new HashSet(); 17 | for(char j:J.toCharArray()){ 18 | set.add(j); 19 | } 20 | int count=0; 21 | for(char s:S.toCharArray()){ 22 | if(set.contains(s)) count++; 23 | } 24 | return count; 25 | 26 | } 27 | 28 | public static void main(String[] args) { 29 | String J="aA"; 30 | String S="aAAbbbb"; 31 | int x=numJewelsInStones(J,S); 32 | System.out.println(x); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /demo901-1000/demo946.java: -------------------------------------------------------------------------------- 1 | package demo901_1000; 2 | 3 | import java.util.Stack; 4 | 5 | /** 6 | * @author:Sun Hongwei 7 | * @2020/2/28 下午6:12 8 | * File Description:栈的压入、弹出序列: 输入两个整数序列,第一个序列表示栈的压入顺序, 9 | * 请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。 10 | * 例如,序列 {1,2,3,4,5} 是某栈的压栈序列,序列 {4,5,3,2,1} 是该压栈序列对应的一个弹出序列, 11 | * 但 {4,3,5,1,2} 就不可能是该压栈序列的弹出序列。 12 | * 13 | * 14 | * 用一个stack模拟栈push和pop的过程 15 | */ 16 | public class demo946 { 17 | public boolean validateStackSequences(int[] pushed, int[] popped) { 18 | if(pushed.length!=popped.length){ 19 | return false; 20 | } 21 | Stack stack=new Stack<>(); 22 | int j=0; 23 | for(int i:pushed){ 24 | stack.push(i); //先依次把每个数压入栈里 25 | while(!stack.isEmpty() && j 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /design_pattern/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /design_pattern/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /design_pattern/design_pattern.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/AbstractFactory/AbstractFactory: -------------------------------------------------------------------------------- 1 | 抽象工厂:AbstractFactory 2 | 3 | 是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。 4 | 5 | 抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品。 6 | 7 | 8 | 使用抽象工厂模式一般要满足以下条件: 9 | 1.系统中有多个产品族,每个具体工厂创建同一族但属于不同等级结构的产品。 10 | 2.系统一次只可能消费其中某一族产品,即同族的产品一起使用。 11 | 12 | 抽象工厂模式除了具有工厂方法模式的优点外,其他主要优点如下: 13 | 1.可以在类的内部对产品族中相关联的多等级产品共同管理,而不必专门引入多个新的类来进行管理。 14 | 2.当增加一个新的产品族时不需要修改原代码,满足开闭原则。 15 | 其缺点是:当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。 16 | 17 | 18 | 抽象工厂模式的主要角色: 19 | 抽象工厂(Abstract Factory):提供了创建产品的接口,它包含多个创建产品的方法 newProduct(),可以创建多个不同等级的产品。 20 | 具体工厂(Concrete Factory):主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。 21 | 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。 22 | 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它 同具体工厂之间是多对一的关系。 23 | 24 | 抽象工厂模式通常适用于以下场景: 25 | 1.当需要创建的对象是一系列相互关联或相互依赖的产品族时,如电器工厂中的电视机、洗衣机、空调等。 26 | 2.系统中有多个产品族,但每次只使用其中的某一族产品。如有人只喜欢穿某一个品牌的衣服和鞋。 27 | 3.系统中提供了产品的类库,且所有产品的接口相同,客户端不依赖产品实例的创建细节和内部结构。 -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/AbstractFactory/AbstractFactory.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/AbstractFactory/AbstractFactory.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/AbstractFactory/AbstractFactory_UML.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/AbstractFactory/AbstractFactory_UML.png -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/AbstractFactory/ConcreteFactoryA.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/AbstractFactory/ConcreteFactoryA.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/AbstractFactory/Product.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/AbstractFactory/Product.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/AbstractFactory/concreteProductA.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/AbstractFactory/concreteProductA.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/AbstractFactory/concreteProductB.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/AbstractFactory/concreteProductB.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Adapter/Adapte: -------------------------------------------------------------------------------- 1 | 适配器模式:Adapter 2 | 3 | 将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。 4 | 5 | 优点: 6 | 1.客户端通过适配器可以透明地调用目标接口。 7 | 2.复用了现存的类,程序员不需要修改原有代码而重用现有的适配者类。 8 | 3.将目标类和适配者类解耦,解决了目标类和适配者类接口不一致的问题。 9 | 10 | 模式结构: 11 | 目标(Target)接口:当前系统业务所期待的接口,它可以是抽象类或接口。 12 | 适配者(Adaptee)类:它是被访问和适配的现存组件库中的组件接口。 13 | 适配器(Adapter)类:它是一个转换器,通过继承或引用适配者的对象,把适配者接口转换成目标接口,让客户按目标接口的格式访问适配者。 14 | -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Adapter/Adaptee.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Adapter/Adaptee.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Adapter/AdapterDemo/ElectricAdapter.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Adapter/AdapterDemo/ElectricAdapter.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Adapter/AdapterDemo/ElectricMotor.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Adapter/AdapterDemo/ElectricMotor.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Adapter/AdapterDemo/Motor.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Adapter/AdapterDemo/Motor.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Adapter/AdapterDemo/MotorAdapterTest.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Adapter/AdapterDemo/MotorAdapterTest.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Adapter/AdapterDemo/OpticalAdapter.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Adapter/AdapterDemo/OpticalAdapter.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Adapter/AdapterDemo/OpticalMotor.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Adapter/AdapterDemo/OpticalMotor.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Adapter/AdapterTest.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Adapter/AdapterTest.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Adapter/Adapter_UML.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Adapter/Adapter_UML.png -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Adapter/ClassAdapter.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Adapter/ClassAdapter.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Adapter/Target.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Adapter/Target.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Decorator/Component.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Decorator/Component.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Decorator/ConcreteComponent.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Decorator/ConcreteComponent.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Decorator/ConcreteDecorator.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Decorator/ConcreteDecorator.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Decorator/Decorate_UML.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Decorator/Decorate_UML.png -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Decorator/Decorator: -------------------------------------------------------------------------------- 1 | 装饰模式:Decorator 2 | 3 | 指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式,它属于对象结构型模式。 4 | 5 | 主要优点有: 6 | 1.采用装饰模式扩展对象的功能比采用继承方式更加灵活。 7 | 2.可以设计出多个不同的具体装饰类,创造出多个不同行为的组合。 8 | 9 | 主要缺点是:装饰模式增加了许多子类,如果过度使用会使程序变得很复杂。 10 | 11 | 模式的结构:装饰模式主要包含以下角色。 12 | 抽象构件(Component)角色:定义一个抽象接口以规范准备接收附加责任的对象。 13 | 具体构件(Concrete Component)角色:实现抽象构件,通过装饰角色为其添加一些职责。 14 | 抽象装饰(Decorator)角色:继承抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。 15 | 具体装饰(ConcreteDecorator)角色:实现抽象装饰的相关方法,并给具体构件对象添加附加的责任。 16 | 17 | 应用场景: 18 | 1.当需要给一个现有类添加附加职责,而又不能采用生成子类的方法进行扩充时。例如,该类被隐藏或者该类是终极类或者采用继承方式会产生大量的子类。 19 | 2.当需要通过对现有的一组基本功能进行排列组合而产生非常多的功能时,采用继承关系很难实现,而采用装饰模式却很好实现。 20 | 3.当对象的功能要求可以动态地添加,也可以再动态地撤销时。 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Decorator/Decorator.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Decorator/Decorator.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Decorator/DecoratorTest.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Decorator/DecoratorTest.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/FactoryMethod/AbstractFactory.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/FactoryMethod/AbstractFactory.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/FactoryMethod/FactoryMethod: -------------------------------------------------------------------------------- 1 | 工厂方法模式:Factory Method 2 | 定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类当中。 3 | 这满足创建型模式中所要求的“创建与使用相分离”的特点。 4 | 5 | 工厂方法模式的主要优点有: 6 | 1.用户只需要知道具体工厂的名称就可得到所要的产品,无须知道产品的具体创建过程; 7 | 2.在系统增加新的产品时只需要添加具体产品类和对应的具体工厂类,无须对原工厂进行任何修改,满足开闭原则; 8 | 9 | 缺点是:每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类,这增加了系统的复杂度。 10 | 11 | 模式的结构 12 | 工厂方法模式的主要角色如下: 13 | 抽象工厂(Abstract Factory):提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法newProduct()来创建产品。 14 | 具体工厂(ConcreteFactory):主要是实现抽象工厂中的抽象方法,完成具体产品的创建。 15 | 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能。 16 | 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应。 17 | 18 | 适用于以下场景: 19 | 1.客户只知道创建产品的工厂名,而不知道具体的产品名。如 TCL 电视工厂、海信电视工厂等。 20 | 2.创建对象的任务由多个具体子工厂中的某一个完成,而抽象工厂只提供创建产品的接口。 21 | 3.客户不关心创建产品的细节,只关心产品的品牌。 -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/FactoryMethod/Factory_Method_UML.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/FactoryMethod/Factory_Method_UML.png -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/FactoryMethod/Factory_Test.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/FactoryMethod/Factory_Test.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/FactoryMethod/Product.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/FactoryMethod/Product.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/FactoryMethod/concreteFactoryA.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/FactoryMethod/concreteFactoryA.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/FactoryMethod/concreteFactoryB.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/FactoryMethod/concreteFactoryB.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/FactoryMethod/concreteProductA.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/FactoryMethod/concreteProductA.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/FactoryMethod/concreteProductB.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/FactoryMethod/concreteProductB.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/META-INF/design_pattern.kotlin_module: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Observer/ConcreteObserver1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Observer/ConcreteObserver1.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Observer/ConcreteObserver2.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Observer/ConcreteObserver2.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Observer/ConcreteSubject.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Observer/ConcreteSubject.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Observer/Observer: -------------------------------------------------------------------------------- 1 | 观察者模式:Observer 2 | 3 | 多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。 4 | 这种模式有时又称作发布-订阅模式、模型-视图模式,它是对象行为型模式。 5 | 6 | 主要优点: 7 | 1.降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。 8 | 2.目标与观察者之间建立了一套触发机制。 9 | 10 | 主要缺点: 11 | 1.目标与观察者之间的依赖关系并没有完全解除,而且有可能出现循环引用。 12 | 2.当观察者对象很多时,通知的发布会花费很多时间,影响程序的效率。 13 | 14 | 模式的结构: 15 | 抽象主题(Subject)角色:也叫抽象目标类,它提供了一个用于保存观察者对象的聚集类和增加、删除观察者对象的方法,以及通知所有观察者的抽象方法。 16 | 具体主题(Concrete Subject)角色:也叫具体目标类,它实现抽象目标中的通知方法,当具体主题的内部状态发生改变时,通知所有注册过的观察者对象。 17 | 抽象观察者(Observer)角色:它是一个抽象类或接口,它包含了一个更新自己的抽象方法,当接到具体主题的更改通知时被调用。 18 | 具体观察者(Concrete Observer)角色:实现抽象观察者中定义的抽象方法,以便在得到目标的更改通知时更新自身的状态。 19 | 20 | 应用场景: 21 | 1.对象间存在一对多关系,一个对象的状态发生改变会影响其他对象。 22 | 2.当一个抽象模型有两个方面,其中一个方面依赖于另一方面时,可将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。 -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Observer/Observer.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Observer/Observer.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Observer/ObserverDemo/Bear.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Observer/ObserverDemo/Bear.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Observer/ObserverDemo/Bull.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Observer/ObserverDemo/Bull.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Observer/ObserverDemo/OilFuture.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Observer/ObserverDemo/OilFuture.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Observer/ObserverDemo/Tests.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Observer/ObserverDemo/Tests.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Observer/ObserverTest.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Observer/ObserverTest.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Observer/Observer_UML.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Observer/Observer_UML.png -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Observer/Subject.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Observer/Subject.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Prototype/Prototype: -------------------------------------------------------------------------------- 1 | 原型模式:Prototype 2 | 用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象。 3 | 在这里,原型实例指定了要创建的对象的种类。用这种方式创建对象非常高效,根本无须知道对象创建的细节。 4 | 5 | 原型模式包含以下主要角色: 6 | 7 | 抽象原型类:规定了具体原型对象必须实现的接口。 8 | 具体原型类:实现抽象原型类的 clone() 方法,它是可被复制的对象。 9 | 访问类:使用具体原型类中的 clone() 方法来复制新的对象。 10 | 11 | 12 | 原型模式通常适用于以下场景: 13 | 1.对象之间相同或相似,即只是个别的几个属性不同的时候。 14 | 2.对象的创建过程比较麻烦,但复制比较简单的时候。 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Prototype/PrototypeTest.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Prototype/PrototypeTest.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Prototype/Prototype_UML.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Prototype/Prototype_UML.png -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Prototype/Realizetype.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Prototype/Realizetype.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Proxy/Proxy: -------------------------------------------------------------------------------- 1 | 代理模式:Proxy 2 | 3 | 通过定义一个继承抽象主题的代理来包含真实主题,从而实现对真实主题的访问。 4 | 5 | 由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象, 6 | 代理对象作为访问对象和目标对象之间的中介。 7 | 8 | 9 | 模式结构: 10 | 抽象主题(Subject)类:通过接口或抽象类声明真实主题和代理对象实现的业务方法。 11 | 真实主题(Real Subject)类:实现了抽象主题中的具体业务,是代理对象所代表的真实对象,是最终要引用的对象。 12 | 代理(Proxy)类:提供了与真实主题相同的接口,其内部含有对真实主题的引用,它可以访问、控制或扩展真实主题的功能。 13 | 14 | 优点: 15 | 1.代理模式在客户端与目标对象之间起到一个中介作用和保护目标对象的作用; 16 | 2.代理对象可以扩展目标对象的功能; 17 | 3.代理模式能将客户端与目标对象分离,在一定程度上降低了系统的耦合度; -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Proxy/Proxy.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Proxy/Proxy.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Proxy/ProxyTest.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Proxy/ProxyTest.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Proxy/Proxy_UML.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Proxy/Proxy_UML.png -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Proxy/RealSubject.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Proxy/RealSubject.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Proxy/Subject.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Proxy/Subject.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Singleton/HungrySingleton.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Singleton/HungrySingleton.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Singleton/LazySingleton.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Singleton/LazySingleton.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Singleton/Singleton: -------------------------------------------------------------------------------- 1 | 单例模式:Singleton 2 | 3 | 为了节省内存资源、保证数据内容的一致性,对某些类要求只能创建一个实例,且该类能自行创建这个实例的一种模式。 4 | 5 | 在计算机系统中,还有 Windows 的回收站、操作系统中的文件系统、多线程中的线程池、 6 | 显卡的驱动程序对象、打印机的后台处理服务、应用程序的日志对象、数据库的连接池、网站的计数器、 7 | Web 应用的配置对象、应用程序中的对话框、系统中的缓存等常常被设计成单例。 8 | 9 | 10 | 11 | 应用场景: 12 | 1.某类只要求生成一个对象时,比如身份证号 13 | 2.当对象需要被共享的场合。可以节省内存,加快对象访问速度。如Web配置对象,数据库连接池等 14 | 3.当某类需要频繁实例化,并且创建对象又频繁被销毁的时候,如多线程的线程池,网络连接池等 -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Singleton/SingletonDemo$Sunhongwei.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Singleton/SingletonDemo$Sunhongwei.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Singleton/SingletonDemo.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Singleton/SingletonDemo.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Singleton/Singleton_UML.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Singleton/Singleton_UML.png -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Strategy/ConcreteStrategyA.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Strategy/ConcreteStrategyA.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Strategy/ConcreteStrategyB.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Strategy/ConcreteStrategyB.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Strategy/Context.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Strategy/Context.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Strategy/Strategy: -------------------------------------------------------------------------------- 1 | 策略模式:Strategy 2 | 3 | 该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。 4 | 策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。 5 | 6 | 7 | 主要优点如下: 8 | 1.多重条件语句不易维护,而使用策略模式可以避免使用多重条件语句。 9 | 2.策略模式提供了一系列的可供重用的算法族,恰当使用继承可以把算法族的公共代码转移到父类里面,从而避免重复的代码。 10 | 3.策略模式可以提供相同行为的不同实现,客户可以根据不同时间或空间要求选择不同的。 11 | 4.策略模式提供了对开闭原则的完美支持,可以在不修改原代码的情况下,灵活增加新算法。 12 | 5.策略模式把算法的使用放到环境类中,而算法的实现移到具体策略类中,实现了二者的分离。 13 | 14 | 主要缺点如下: 15 | 1.客户端必须理解所有策略算法的区别,以便适时选择恰当的算法类。 16 | 2.策略模式造成很多的策略类。 17 | 18 | 19 | 策略模式的主要角色如下。 20 | 1.抽象策略(Strategy)类:定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。 21 | 2.具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现。 22 | 3.环境(Context)类:持有一个策略类的引用,最终给客户端调用。 23 | -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Strategy/Strategy.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Strategy/Strategy.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Strategy/StrategyTest.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Strategy/StrategyTest.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/Strategy/Strategy_UML.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/Strategy/Strategy_UML.png -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/TemplateMethod/AbstractClass.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/TemplateMethod/AbstractClass.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/TemplateMethod/ConcreteClass.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/TemplateMethod/ConcreteClass.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/TemplateMethod/TemplateMethod: -------------------------------------------------------------------------------- 1 | 模板方法模式:TemplateMethod 2 | 3 | 定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。 4 | 它是一种类行为型模式。 5 | 6 | 主要优点如下: 7 | 1.它封装了不变部分,扩展可变部分。它把认为是不变部分的算法封装到父类中实现,而把可变部分算法由子类继承实现,便于子类继续扩展。 8 | 2.它在父类中提取了公共的部分代码,便于代码复用。 9 | 3.部分方法是由子类实现的,因此子类可以通过扩展方式增加相应的功能,符合开闭原则。 10 | 11 | 该模式的主要缺点如下: 12 | 1.对每个不同的实现都需要定义一个子类,这会导致类的个数增加,系统更加庞大,设计也更加抽象。 13 | 2.父类中的抽象方法由子类实现,子类执行的结果会影响父类的结果,这导致一种反向的控制结构,它提高了代码阅读的难度。 14 | 15 | 16 | 模板方法模式包含以下主要角色。 17 | 18 | (1) 抽象类(Abstract Class):负责给出一个算法的轮廓和骨架。它由一个模板方法和若干个基本方法构成。这些方法的定义如下。 19 | 20 | ① 模板方法:定义了算法的骨架,按某种顺序调用其包含的基本方法。 21 | 22 | ② 基本方法:是整个算法中的一个步骤,包含以下几种类型。 23 | 抽象方法:在抽象类中申明,由具体子类实现。 24 | 具体方法:在抽象类中已经实现,在具体子类中可以继承或重写它。 25 | 钩子方法:在抽象类中已经实现,包括用于判断的逻辑方法和需要子类重写的空方法两种。 26 | 27 | (2) 具体子类(Concrete Class):实现抽象类中所定义的抽象方法和钩子方法,它们是一个顶级逻辑的一个组成步骤 28 | 29 | 30 | 模板方法模式通常适用于以下场景: 31 | 1.算法的整体步骤很固定,但其中个别部分易变时,这时候可以使用模板方法模式,将容易变的部分抽象出来,供子类实现。 32 | 2.当多个子类存在公共的行为时,可以将其提取出来并集中到一个公共父类中以避免代码重复。首先,要识别现有代码中的不同之处,并且将不同之处分离为新的操作。最后,用一个调用这些新的操作的模板方法来替换这些不同的代码。 33 | 3.当需要控制子类的扩展时,模板方法只在特定点调用钩子操作,这样就只允许在这些点进行扩展。 34 | 35 | 36 | -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/TemplateMethod/TemplateMethodTest.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/TemplateMethod/TemplateMethodTest.class -------------------------------------------------------------------------------- /design_pattern/out/production/design_pattern/TemplateMethod/TemplateMethod_UML.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/out/production/design_pattern/TemplateMethod/TemplateMethod_UML.png -------------------------------------------------------------------------------- /design_pattern/src/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/src/.DS_Store -------------------------------------------------------------------------------- /design_pattern/src/AbstractFactory/AbstractFactory: -------------------------------------------------------------------------------- 1 | 抽象工厂:AbstractFactory 2 | 3 | 是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。 4 | 5 | 抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品。 6 | 7 | 8 | 使用抽象工厂模式一般要满足以下条件: 9 | 1.系统中有多个产品族,每个具体工厂创建同一族但属于不同等级结构的产品。 10 | 2.系统一次只可能消费其中某一族产品,即同族的产品一起使用。 11 | 12 | 抽象工厂模式除了具有工厂方法模式的优点外,其他主要优点如下: 13 | 1.可以在类的内部对产品族中相关联的多等级产品共同管理,而不必专门引入多个新的类来进行管理。 14 | 2.当增加一个新的产品族时不需要修改原代码,满足开闭原则。 15 | 其缺点是:当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。 16 | 17 | 18 | 抽象工厂模式的主要角色: 19 | 抽象工厂(Abstract Factory):提供了创建产品的接口,它包含多个创建产品的方法 newProduct(),可以创建多个不同等级的产品。 20 | 具体工厂(Concrete Factory):主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。 21 | 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。 22 | 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它 同具体工厂之间是多对一的关系。 23 | 24 | 抽象工厂模式通常适用于以下场景: 25 | 1.当需要创建的对象是一系列相互关联或相互依赖的产品族时,如电器工厂中的电视机、洗衣机、空调等。 26 | 2.系统中有多个产品族,但每次只使用其中的某一族产品。如有人只喜欢穿某一个品牌的衣服和鞋。 27 | 3.系统中提供了产品的类库,且所有产品的接口相同,客户端不依赖产品实例的创建细节和内部结构。 -------------------------------------------------------------------------------- /design_pattern/src/AbstractFactory/AbstractFactory.java: -------------------------------------------------------------------------------- 1 | package AbstractFactory; 2 | 3 | import FactoryMethod.Product; 4 | 5 | /** 6 | * @author:Sun Hongwei 7 | * @2020/3/13 下午11:26 8 | * File Description:抽象工厂:提供了产品的生成方法。 9 | */ 10 | public interface AbstractFactory { 11 | public concreteProductA newProductA(); 12 | public concreteProductB newProductB(); 13 | } 14 | -------------------------------------------------------------------------------- /design_pattern/src/AbstractFactory/AbstractFactory_UML.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/src/AbstractFactory/AbstractFactory_UML.png -------------------------------------------------------------------------------- /design_pattern/src/AbstractFactory/ConcreteFactoryA.java: -------------------------------------------------------------------------------- 1 | package AbstractFactory; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/13 下午11:28 6 | * File Description:具体工厂:实现了产品的生成方法。 7 | */ 8 | public class ConcreteFactoryA implements AbstractFactory{ 9 | public concreteProductA newProductA(){ 10 | System.out.println("具体工厂 1 生成-->具体产品 11..."); 11 | return new concreteProductA(); 12 | } 13 | 14 | public concreteProductB newProductB(){ 15 | System.out.println("具体工厂 2 生成-->具体产品 22..."); 16 | return new concreteProductB(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /design_pattern/src/AbstractFactory/Product.java: -------------------------------------------------------------------------------- 1 | package AbstractFactory; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/13 下午9:59 6 | * File Description:抽象产品:提供了产品的接口 7 | */ 8 | public interface Product { 9 | public void show(); 10 | } 11 | -------------------------------------------------------------------------------- /design_pattern/src/AbstractFactory/concreteProductA.java: -------------------------------------------------------------------------------- 1 | package AbstractFactory; 2 | 3 | import FactoryMethod.Product; 4 | 5 | /** 6 | * @author:Sun Hongwei 7 | * @2020/3/13 下午10:01 8 | * File Description:具体产品A:实现抽象产品中的抽象方法 9 | */ 10 | public class concreteProductA implements Product { 11 | public void show(){ 12 | System.out.println("具体产品A:-______-"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /design_pattern/src/AbstractFactory/concreteProductB.java: -------------------------------------------------------------------------------- 1 | package AbstractFactory; 2 | 3 | import FactoryMethod.Product; 4 | 5 | /** 6 | * @author:Sun Hongwei 7 | * @2020/3/13 下午10:02 8 | * File Description:具体产品B:实现抽象产品中的抽象方法 9 | */ 10 | public class concreteProductB implements Product { 11 | public void show(){ 12 | System.out.println("具体产品B:-______-"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /design_pattern/src/Adapter/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/src/Adapter/.DS_Store -------------------------------------------------------------------------------- /design_pattern/src/Adapter/Adapte: -------------------------------------------------------------------------------- 1 | 适配器模式:Adapter 2 | 3 | 将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。 4 | 5 | 优点: 6 | 1.客户端通过适配器可以透明地调用目标接口。 7 | 2.复用了现存的类,程序员不需要修改原有代码而重用现有的适配者类。 8 | 3.将目标类和适配者类解耦,解决了目标类和适配者类接口不一致的问题。 9 | 10 | 模式结构: 11 | 目标(Target)接口:当前系统业务所期待的接口,它可以是抽象类或接口。 12 | 适配者(Adaptee)类:它是被访问和适配的现存组件库中的组件接口。 13 | 适配器(Adapter)类:它是一个转换器,通过继承或引用适配者的对象,把适配者接口转换成目标接口,让客户按目标接口的格式访问适配者。 14 | -------------------------------------------------------------------------------- /design_pattern/src/Adapter/Adaptee.java: -------------------------------------------------------------------------------- 1 | package Adapter; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/11 下午7:14 6 | * File Description:适配器接口 7 | */ 8 | public class Adaptee { 9 | public void specificRequest(){ 10 | System.out.println("适配器"); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /design_pattern/src/Adapter/AdapterDemo/ElectricAdapter.java: -------------------------------------------------------------------------------- 1 | package Adapter.AdapterDemo; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/13 下午6:58 6 | * File Description:电能适配器,引入Motor接口 7 | */ 8 | public class ElectricAdapter implements Motor{ 9 | // 适配器内创建ElectricMotor实例对象 10 | private ElectricMotor emoter; 11 | public ElectricAdapter(){ 12 | emoter=new ElectricMotor(); 13 | } 14 | 15 | public void drive(){ 16 | emoter.electricDrive(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /design_pattern/src/Adapter/AdapterDemo/ElectricMotor.java: -------------------------------------------------------------------------------- 1 | package Adapter.AdapterDemo; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/13 下午6:54 6 | * File Description:适配者1:电能发动机 7 | */ 8 | public class ElectricMotor { 9 | public void electricDrive(){ 10 | System.out.println("电能发动机!"); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /design_pattern/src/Adapter/AdapterDemo/Motor.java: -------------------------------------------------------------------------------- 1 | package Adapter.AdapterDemo; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/13 下午6:53 6 | * File Description:目标类:Motor(发动机) 7 | */ 8 | public interface Motor { 9 | public void drive(); 10 | } 11 | -------------------------------------------------------------------------------- /design_pattern/src/Adapter/AdapterDemo/MotorAdapterTest.java: -------------------------------------------------------------------------------- 1 | package Adapter.AdapterDemo; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/13 下午7:06 6 | * File Description:Adapter测试类 7 | */ 8 | public class MotorAdapterTest { 9 | public static void main(String[] args) { 10 | System.out.println("适配者模式调用: "); 11 | OpticalAdapter opticalAdapter=new OpticalAdapter(); 12 | opticalAdapter.drive(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /design_pattern/src/Adapter/AdapterDemo/OpticalAdapter.java: -------------------------------------------------------------------------------- 1 | package Adapter.AdapterDemo; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/13 下午7:02 6 | * File Description:OpticalAdapter:光能适配器 7 | */ 8 | public class OpticalAdapter { 9 | //通过适配器类来创建motor类实例对象,并且调用motor类的方法 10 | private OpticalMotor omoter; 11 | public OpticalAdapter(){ 12 | omoter=new OpticalMotor(); 13 | } 14 | public void drive(){ 15 | omoter.opticalDrive(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /design_pattern/src/Adapter/AdapterDemo/OpticalMotor.java: -------------------------------------------------------------------------------- 1 | package Adapter.AdapterDemo; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/13 下午6:56 6 | * File Description:适配者2:光能发动机 7 | */ 8 | public class OpticalMotor { 9 | public void opticalDrive(){ 10 | System.out.println("光能发动机! "); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /design_pattern/src/Adapter/AdapterTest.java: -------------------------------------------------------------------------------- 1 | package Adapter; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/11 下午7:32 6 | * File Description:Adapter测试类 7 | */ 8 | public class AdapterTest { 9 | public static void main(String[] args) { 10 | System.out.println("适配器模式测试开始:"); 11 | Target target=new ClassAdapter(); 12 | target.request(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /design_pattern/src/Adapter/Adapter_UML.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/src/Adapter/Adapter_UML.png -------------------------------------------------------------------------------- /design_pattern/src/Adapter/ClassAdapter.java: -------------------------------------------------------------------------------- 1 | package Adapter; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/11 下午7:31 6 | * File Description:适配器类 7 | */ 8 | public class ClassAdapter extends Adaptee implements Target{ 9 | @Override 10 | public void request(){ 11 | specificRequest(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /design_pattern/src/Adapter/Target.java: -------------------------------------------------------------------------------- 1 | package Adapter; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/11 下午7:11 6 | * File Description:目标接口 7 | */ 8 | public interface Target { 9 | public void request(); 10 | } 11 | -------------------------------------------------------------------------------- /design_pattern/src/Decorator/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/src/Decorator/.DS_Store -------------------------------------------------------------------------------- /design_pattern/src/Decorator/Component.java: -------------------------------------------------------------------------------- 1 | package Decorator; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/13 下午11:58 6 | * File Description:抽象构件角色 7 | */ 8 | public interface Component { 9 | public void operation(); 10 | } 11 | -------------------------------------------------------------------------------- /design_pattern/src/Decorator/ConcreteComponent.java: -------------------------------------------------------------------------------- 1 | package Decorator; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/13 下午11:58 6 | * File Description:具体构件角色 7 | */ 8 | public class ConcreteComponent implements Component{ 9 | public ConcreteComponent(){ 10 | System.out.println("创建具体构件角色"); 11 | } 12 | 13 | public void operation(){ 14 | System.out.println("调用具体构件角色的方法operation()"); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /design_pattern/src/Decorator/ConcreteDecorator.java: -------------------------------------------------------------------------------- 1 | package Decorator; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/14 上午12:03 6 | * File Description:具体装饰角色 7 | */ 8 | public class ConcreteDecorator extends Decorator{ 9 | public ConcreteDecorator(Component component){ 10 | super(component); 11 | } 12 | 13 | public void operation(){ 14 | super.operation(); 15 | addFunction(); 16 | } 17 | 18 | public void addFunction(){ 19 | System.out.println("为具体构件角色增加额外的功能addedFunction()"); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /design_pattern/src/Decorator/Decorate_UML.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/src/Decorator/Decorate_UML.png -------------------------------------------------------------------------------- /design_pattern/src/Decorator/Decorator: -------------------------------------------------------------------------------- 1 | 装饰模式:Decorator 2 | 3 | 指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式,它属于对象结构型模式。 4 | 5 | 主要优点有: 6 | 1.采用装饰模式扩展对象的功能比采用继承方式更加灵活。 7 | 2.可以设计出多个不同的具体装饰类,创造出多个不同行为的组合。 8 | 9 | 主要缺点是:装饰模式增加了许多子类,如果过度使用会使程序变得很复杂。 10 | 11 | 模式的结构:装饰模式主要包含以下角色。 12 | 抽象构件(Component)角色:定义一个抽象接口以规范准备接收附加责任的对象。 13 | 具体构件(Concrete Component)角色:实现抽象构件,通过装饰角色为其添加一些职责。 14 | 抽象装饰(Decorator)角色:继承抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。 15 | 具体装饰(ConcreteDecorator)角色:实现抽象装饰的相关方法,并给具体构件对象添加附加的责任。 16 | 17 | 应用场景: 18 | 1.当需要给一个现有类添加附加职责,而又不能采用生成子类的方法进行扩充时。例如,该类被隐藏或者该类是终极类或者采用继承方式会产生大量的子类。 19 | 2.当需要通过对现有的一组基本功能进行排列组合而产生非常多的功能时,采用继承关系很难实现,而采用装饰模式却很好实现。 20 | 3.当对象的功能要求可以动态地添加,也可以再动态地撤销时。 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /design_pattern/src/Decorator/Decorator.java: -------------------------------------------------------------------------------- 1 | package Decorator; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/14 上午12:00 6 | * File Description:抽象装饰角色 7 | */ 8 | public class Decorator implements Component{ 9 | private Component component; 10 | public Decorator(Component component){ 11 | this.component=component; 12 | } 13 | 14 | public void operation(){ 15 | component.operation(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /design_pattern/src/Decorator/DecoratorTest.java: -------------------------------------------------------------------------------- 1 | package Decorator; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/14 上午12:23 6 | * File Description:装饰模式测试 7 | */ 8 | public class DecoratorTest { 9 | public static void main(String[] args) { 10 | Component p=new ConcreteComponent(); 11 | p.operation(); 12 | System.out.println("----------"); 13 | Component d=new ConcreteDecorator(p); 14 | d.operation(); 15 | 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /design_pattern/src/FactoryMethod/AbstractFactory.java: -------------------------------------------------------------------------------- 1 | package FactoryMethod; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/13 下午10:00 6 | * File Description:抽象工厂:提供了厂品的生成方法 7 | */ 8 | public interface AbstractFactory { 9 | public Product newProduct(); 10 | } 11 | -------------------------------------------------------------------------------- /design_pattern/src/FactoryMethod/FactoryMethod: -------------------------------------------------------------------------------- 1 | 工厂方法模式:Factory Method 2 | 定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类当中。 3 | 这满足创建型模式中所要求的“创建与使用相分离”的特点。 4 | 5 | 工厂方法模式的主要优点有: 6 | 1.用户只需要知道具体工厂的名称就可得到所要的产品,无须知道产品的具体创建过程; 7 | 2.在系统增加新的产品时只需要添加具体产品类和对应的具体工厂类,无须对原工厂进行任何修改,满足开闭原则; 8 | 9 | 缺点是:每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类,这增加了系统的复杂度。 10 | 11 | 模式的结构 12 | 工厂方法模式的主要角色如下: 13 | 抽象工厂(Abstract Factory):提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法newProduct()来创建产品。 14 | 具体工厂(ConcreteFactory):主要是实现抽象工厂中的抽象方法,完成具体产品的创建。 15 | 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能。 16 | 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应。 17 | 18 | 适用于以下场景: 19 | 1.客户只知道创建产品的工厂名,而不知道具体的产品名。如 TCL 电视工厂、海信电视工厂等。 20 | 2.创建对象的任务由多个具体子工厂中的某一个完成,而抽象工厂只提供创建产品的接口。 21 | 3.客户不关心创建产品的细节,只关心产品的品牌。 -------------------------------------------------------------------------------- /design_pattern/src/FactoryMethod/Factory_Method_UML.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/src/FactoryMethod/Factory_Method_UML.png -------------------------------------------------------------------------------- /design_pattern/src/FactoryMethod/Factory_Test.java: -------------------------------------------------------------------------------- 1 | package FactoryMethod; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/13 下午10:09 6 | * File Description:工厂方法测试类 7 | */ 8 | public class Factory_Test { 9 | public static void main(String[] args) { 10 | try { 11 | AbstractFactory fa=new concreteFactoryA(); 12 | Product pa=fa.newProduct(); 13 | pa.show(); 14 | 15 | AbstractFactory fb=new concreteFactoryB(); 16 | Product pb=fb.newProduct(); 17 | pb.show(); 18 | 19 | }catch (Exception e){ 20 | System.out.println(e.getMessage()); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /design_pattern/src/FactoryMethod/Product.java: -------------------------------------------------------------------------------- 1 | package FactoryMethod; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/13 下午9:59 6 | * File Description:抽象产品:提供了产品的接口 7 | */ 8 | public interface Product { 9 | public void show(); 10 | } 11 | -------------------------------------------------------------------------------- /design_pattern/src/FactoryMethod/concreteFactoryA.java: -------------------------------------------------------------------------------- 1 | package FactoryMethod; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/13 下午10:07 6 | * File Description:具体工厂A:实现了产品A的生成方法 7 | */ 8 | public class concreteFactoryA implements AbstractFactory { 9 | public Product newProduct(){ 10 | System.out.println("具体工厂A生成-->具体产品A..."); 11 | return new concreteProductA(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /design_pattern/src/FactoryMethod/concreteFactoryB.java: -------------------------------------------------------------------------------- 1 | package FactoryMethod; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/13 下午10:08 6 | * File Description:具体工厂B:实现了产品B的生成方法 7 | */ 8 | public class concreteFactoryB implements AbstractFactory { 9 | public Product newProduct(){ 10 | System.out.println("具体工厂B生成-->具体产品B..."); 11 | return new concreteProductB(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /design_pattern/src/FactoryMethod/concreteProductA.java: -------------------------------------------------------------------------------- 1 | package FactoryMethod; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/13 下午10:01 6 | * File Description:具体产品A:实现抽象产品中的抽象方法 7 | */ 8 | public class concreteProductA implements Product { 9 | public void show(){ 10 | System.out.println("具体产品A:-______-"); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /design_pattern/src/FactoryMethod/concreteProductB.java: -------------------------------------------------------------------------------- 1 | package FactoryMethod; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/13 下午10:02 6 | * File Description:具体产品B:实现抽象产品中的抽象方法 7 | */ 8 | public class concreteProductB implements Product{ 9 | public void show(){ 10 | System.out.println("具体产品B:-______-"); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /design_pattern/src/Observer/ConcreteObserver1.java: -------------------------------------------------------------------------------- 1 | package Observer; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/11 下午5:44 6 | * File Description:具体观察者1 7 | */ 8 | public class ConcreteObserver1 implements Observer{ 9 | public void response(){ 10 | System.out.println("观察者1做出回应!—————————————>"); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /design_pattern/src/Observer/ConcreteObserver2.java: -------------------------------------------------------------------------------- 1 | package Observer; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/11 下午5:46 6 | * File Description:具体观察者2 7 | */ 8 | public class ConcreteObserver2 implements Observer{ 9 | public void response(){ 10 | System.out.println("观察者2做出回应!—————————————>"); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /design_pattern/src/Observer/ConcreteSubject.java: -------------------------------------------------------------------------------- 1 | package Observer; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/11 下午6:00 6 | * File Description:具体目标 7 | */ 8 | public class ConcreteSubject extends Subject{ 9 | 10 | @Override 11 | public void notifyObserver(){ 12 | System.out.println("具体的目标——————————————"); 13 | for(Object obs:observers){ 14 | ((Observer)obs).response(); 15 | } 16 | 17 | } 18 | 19 | 20 | } 21 | -------------------------------------------------------------------------------- /design_pattern/src/Observer/Observer: -------------------------------------------------------------------------------- 1 | 观察者模式:Observer 2 | 3 | 多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。 4 | 这种模式有时又称作发布-订阅模式、模型-视图模式,它是对象行为型模式。 5 | 6 | 主要优点: 7 | 1.降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。 8 | 2.目标与观察者之间建立了一套触发机制。 9 | 10 | 主要缺点: 11 | 1.目标与观察者之间的依赖关系并没有完全解除,而且有可能出现循环引用。 12 | 2.当观察者对象很多时,通知的发布会花费很多时间,影响程序的效率。 13 | 14 | 模式的结构: 15 | 抽象主题(Subject)角色:也叫抽象目标类,它提供了一个用于保存观察者对象的聚集类和增加、删除观察者对象的方法,以及通知所有观察者的抽象方法。 16 | 具体主题(Concrete Subject)角色:也叫具体目标类,它实现抽象目标中的通知方法,当具体主题的内部状态发生改变时,通知所有注册过的观察者对象。 17 | 抽象观察者(Observer)角色:它是一个抽象类或接口,它包含了一个更新自己的抽象方法,当接到具体主题的更改通知时被调用。 18 | 具体观察者(Concrete Observer)角色:实现抽象观察者中定义的抽象方法,以便在得到目标的更改通知时更新自身的状态。 19 | 20 | 应用场景: 21 | 1.对象间存在一对多关系,一个对象的状态发生改变会影响其他对象。 22 | 2.当一个抽象模型有两个方面,其中一个方面依赖于另一方面时,可将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。 -------------------------------------------------------------------------------- /design_pattern/src/Observer/Observer.java: -------------------------------------------------------------------------------- 1 | package Observer; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/11 下午5:32 6 | * File Description:抽象观察者 7 | */ 8 | public interface Observer { 9 | void response(); 10 | } 11 | -------------------------------------------------------------------------------- /design_pattern/src/Observer/ObserverDemo/Bear.java: -------------------------------------------------------------------------------- 1 | package Observer.ObserverDemo; 2 | 3 | import java.util.Observer; 4 | import java.util.Observable; 5 | 6 | /** 7 | * @author:Sun Hongwei 8 | * @2020/3/13 下午7:43 9 | * File Description:具体观察者类:空方 10 | */ 11 | public class Bear implements Observer { 12 | public void update(Observable o, Object arg){ 13 | Float price=((Float)arg).floatValue(); 14 | if(price>0){ 15 | System.out.println("空方发现: oil上涨"+price+"元! "); 16 | }else{ 17 | System.out.println("空方发现: oil下跌"+(-price)+"元! "); 18 | } 19 | } 20 | 21 | public void response(){ 22 | System.out.println("response"); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /design_pattern/src/Observer/ObserverDemo/Bull.java: -------------------------------------------------------------------------------- 1 | package Observer.ObserverDemo; 2 | 3 | import java.util.Observer; 4 | import java.util.Observable; 5 | 6 | 7 | /** 8 | * @author:Sun Hongwei 9 | * @2020/3/13 下午7:23 10 | * File Description:具体观察者:多方 11 | */ 12 | public class Bull implements Observer { 13 | public void update(Observable o, Object arg){ 14 | Float price=((Float)arg).floatValue(); 15 | if(price>0){ 16 | System.out.println("多方发现: oil上涨"+price+"元! "); 17 | }else{ 18 | System.out.println("多方发现: oil下跌"+(-price)+"元! "); 19 | } 20 | } 21 | 22 | public void response(){ 23 | System.out.println("response"); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /design_pattern/src/Observer/ObserverDemo/OilFuture.java: -------------------------------------------------------------------------------- 1 | package Observer.ObserverDemo; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.Observable; 6 | import java.util.Observer; 7 | 8 | 9 | /** 10 | * @author:Sun Hongwei 11 | * @2020/3/13 下午7:17 12 | * File Description:具体目标:OilFuture原油期货 13 | */ 14 | public class OilFuture extends Observable { 15 | private float price; 16 | public float getPrice(){ 17 | return this.price; 18 | } 19 | public void setPrice(float price){ 20 | super.setChanged(); //设置内部标志位,注明数据发生变化 21 | super.notifyObservers(price); //通知观察者价格改变了 22 | this.price=price; 23 | } 24 | 25 | protected List observers=new ArrayList(); 26 | //增加观察者 27 | public void add(Observer observer){ 28 | observers.add(observer); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /design_pattern/src/Observer/ObserverDemo/Tests.java: -------------------------------------------------------------------------------- 1 | package Observer.ObserverDemo; 2 | 3 | import java.util.Observer; 4 | import java.util.Observable; 5 | 6 | /** 7 | * @author:Sun Hongwei 8 | * @2020/3/13 下午7:27 9 | * File Description:Observer测试类 10 | */ 11 | public class Tests { 12 | public static void main(String[] args) { 13 | OilFuture oilFuture=new OilFuture(); 14 | Observer bull=new Bull(); //多方 15 | Observer bear=new Bear(); //空方 16 | 17 | oilFuture.addObserver(bull); 18 | oilFuture.addObserver(bear); 19 | oilFuture.setPrice(10); 20 | oilFuture.setPrice(-3); 21 | 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /design_pattern/src/Observer/ObserverTest.java: -------------------------------------------------------------------------------- 1 | package Observer; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/11 下午5:47 6 | * File Description:Observer测试类 7 | */ 8 | public class ObserverTest { 9 | public static void main(String[] args) { 10 | Subject subject=new ConcreteSubject(); 11 | Observer obs1=new ConcreteObserver1(); 12 | Observer obs2=new ConcreteObserver2(); 13 | subject.add(obs1); 14 | subject.add(obs2); 15 | subject.notifyObserver(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /design_pattern/src/Observer/Observer_UML.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/src/Observer/Observer_UML.png -------------------------------------------------------------------------------- /design_pattern/src/Observer/Subject.java: -------------------------------------------------------------------------------- 1 | package Observer; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * @author:Sun Hongwei 8 | * @2020/3/11 下午5:42 9 | * File Description:抽象目标 10 | */ 11 | abstract class Subject { 12 | protected List observers=new ArrayList(); 13 | 14 | //增加观察者 15 | public void add(Observer observer){ 16 | observers.add(observer); 17 | } 18 | 19 | //删除观察者 20 | public void delete(Observer observer){ 21 | observers.remove(observer); 22 | } 23 | 24 | //通知观察者 25 | public abstract void notifyObserver(); 26 | 27 | } 28 | -------------------------------------------------------------------------------- /design_pattern/src/Prototype/Prototype: -------------------------------------------------------------------------------- 1 | 原型模式:Prototype 2 | 用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象。 3 | 在这里,原型实例指定了要创建的对象的种类。用这种方式创建对象非常高效,根本无须知道对象创建的细节。 4 | 5 | 原型模式包含以下主要角色: 6 | 7 | 抽象原型类:规定了具体原型对象必须实现的接口。 8 | 具体原型类:实现抽象原型类的 clone() 方法,它是可被复制的对象。 9 | 访问类:使用具体原型类中的 clone() 方法来复制新的对象。 10 | 11 | 12 | 原型模式通常适用于以下场景: 13 | 1.对象之间相同或相似,即只是个别的几个属性不同的时候。 14 | 2.对象的创建过程比较麻烦,但复制比较简单的时候。 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /design_pattern/src/Prototype/PrototypeTest.java: -------------------------------------------------------------------------------- 1 | package Prototype; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/13 下午11:48 6 | * File Description:原型模式的测试类 7 | */ 8 | public class PrototypeTest { 9 | public static void main(String[] args) throws CloneNotSupportedException{ 10 | Realizetype obj1=new Realizetype(); 11 | Realizetype obj2=(Realizetype)obj1.clone(); 12 | System.out.println("obj1==obj2? "+(obj1==obj2)); 13 | 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /design_pattern/src/Prototype/Prototype_UML.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/src/Prototype/Prototype_UML.png -------------------------------------------------------------------------------- /design_pattern/src/Prototype/Realizetype.java: -------------------------------------------------------------------------------- 1 | package Prototype; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/13 下午11:46 6 | * File Description:具体原型类 7 | */ 8 | public class Realizetype implements Cloneable{ 9 | Realizetype(){ 10 | System.out.println("具体原型创建成功"); 11 | } 12 | public Object clone() throws CloneNotSupportedException{ 13 | System.out.println("具体原型复制成功"); 14 | return (Realizetype)super.clone(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /design_pattern/src/Proxy/Proxy: -------------------------------------------------------------------------------- 1 | 代理模式:Proxy 2 | 3 | 通过定义一个继承抽象主题的代理来包含真实主题,从而实现对真实主题的访问。 4 | 5 | 由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象, 6 | 代理对象作为访问对象和目标对象之间的中介。 7 | 8 | 9 | 模式结构: 10 | 抽象主题(Subject)类:通过接口或抽象类声明真实主题和代理对象实现的业务方法。 11 | 真实主题(Real Subject)类:实现了抽象主题中的具体业务,是代理对象所代表的真实对象,是最终要引用的对象。 12 | 代理(Proxy)类:提供了与真实主题相同的接口,其内部含有对真实主题的引用,它可以访问、控制或扩展真实主题的功能。 13 | 14 | 优点: 15 | 1.代理模式在客户端与目标对象之间起到一个中介作用和保护目标对象的作用; 16 | 2.代理对象可以扩展目标对象的功能; 17 | 3.代理模式能将客户端与目标对象分离,在一定程度上降低了系统的耦合度; -------------------------------------------------------------------------------- /design_pattern/src/Proxy/Proxy.java: -------------------------------------------------------------------------------- 1 | package Proxy; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/11 下午3:04 6 | * File Description:代理 7 | */ 8 | public class Proxy implements Subject{ 9 | private RealSubject realSubject; 10 | 11 | public void request(){ 12 | if (realSubject == null) { 13 | realSubject=new RealSubject(); 14 | } 15 | preRequest(); 16 | realSubject.request(); 17 | postRequest(); 18 | } 19 | 20 | public void preRequest(){ 21 | System.out.println("访问前处理----"); 22 | } 23 | public void postRequest(){ 24 | System.out.println("访问后处理----"); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /design_pattern/src/Proxy/ProxyTest.java: -------------------------------------------------------------------------------- 1 | package Proxy; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/11 下午2:49 6 | * File Description:Proxy测试 7 | */ 8 | public class ProxyTest { 9 | public static void main(String[] args) { 10 | Proxy proxy=new Proxy(); 11 | proxy.request(); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /design_pattern/src/Proxy/Proxy_UML.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/src/Proxy/Proxy_UML.png -------------------------------------------------------------------------------- /design_pattern/src/Proxy/RealSubject.java: -------------------------------------------------------------------------------- 1 | package Proxy; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/11 下午2:49 6 | * File Description:真实主题 7 | */ 8 | public class RealSubject implements Subject{ 9 | public void request(){ 10 | System.out.println("访问真实主题"); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /design_pattern/src/Proxy/Subject.java: -------------------------------------------------------------------------------- 1 | package Proxy; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/11 下午2:58 6 | * File Description:抽象主题 7 | */ 8 | public interface Subject { 9 | void request(); 10 | } 11 | -------------------------------------------------------------------------------- /design_pattern/src/Singleton/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/src/Singleton/.DS_Store -------------------------------------------------------------------------------- /design_pattern/src/Singleton/HungrySingleton.java: -------------------------------------------------------------------------------- 1 | package Singleton; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/11 下午2:13 6 | * File Description:饿汉式单例:类一旦加载的时候,就创建一个单例 7 | */ 8 | public class HungrySingleton { 9 | private static final HungrySingleton instance=new HungrySingleton(); 10 | private HungrySingleton(){}; 11 | public static HungrySingleton getInstance(){ 12 | return instance; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /design_pattern/src/Singleton/LazySingleton.java: -------------------------------------------------------------------------------- 1 | package Singleton; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/11 下午2:02 6 | * File Description:懒汉式单例模式:类加载时不会生成单例,只有第一次getInstance时会创建这个单例 7 | */ 8 | public class LazySingleton { 9 | //保证instance在所有线程同步 10 | private static volatile LazySingleton instance=null; 11 | private LazySingleton(){} //避免类在外部实例化 12 | 13 | public static synchronized LazySingleton getInstance() { 14 | if(instance==null){ 15 | instance=new LazySingleton(); 16 | } 17 | return instance; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /design_pattern/src/Singleton/Singleton: -------------------------------------------------------------------------------- 1 | 单例模式:Singleton 2 | 3 | 为了节省内存资源、保证数据内容的一致性,对某些类要求只能创建一个实例,且该类能自行创建这个实例的一种模式。 4 | 5 | 在计算机系统中,还有 Windows 的回收站、操作系统中的文件系统、多线程中的线程池、 6 | 显卡的驱动程序对象、打印机的后台处理服务、应用程序的日志对象、数据库的连接池、网站的计数器、 7 | Web 应用的配置对象、应用程序中的对话框、系统中的缓存等常常被设计成单例。 8 | 9 | 10 | 11 | 应用场景: 12 | 1.某类只要求生成一个对象时,比如身份证号 13 | 2.当对象需要被共享的场合。可以节省内存,加快对象访问速度。如Web配置对象,数据库连接池等 14 | 3.当某类需要频繁实例化,并且创建对象又频繁被销毁的时候,如多线程的线程池,网络连接池等 -------------------------------------------------------------------------------- /design_pattern/src/Singleton/Singleton_UML.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/src/Singleton/Singleton_UML.png -------------------------------------------------------------------------------- /design_pattern/src/Strategy/ConcreteStrategyA.java: -------------------------------------------------------------------------------- 1 | package Strategy; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/15 下午3:04 6 | * File Description:具体策略类A 7 | */ 8 | public class ConcreteStrategyA implements Strategy{ 9 | public void strategyMethod(){ 10 | System.out.println("具体策略A的策略方法被访问!"); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /design_pattern/src/Strategy/ConcreteStrategyB.java: -------------------------------------------------------------------------------- 1 | package Strategy; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/15 下午3:07 6 | * File Description:具体策略类B 7 | */ 8 | public class ConcreteStrategyB implements Strategy { 9 | public void strategyMethod(){ 10 | System.out.println("具体策略B的策略方法被访问!"); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /design_pattern/src/Strategy/Context.java: -------------------------------------------------------------------------------- 1 | package Strategy; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/15 下午3:26 6 | * File Description:环境类 7 | */ 8 | public class Context { 9 | private Strategy strategy; 10 | public Strategy getStrategy(){ 11 | return strategy; 12 | } 13 | public void setStrategy(Strategy strategy){ 14 | this.strategy=strategy; 15 | } 16 | public void strategyMethod(){ 17 | strategy.strategyMethod(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /design_pattern/src/Strategy/Strategy: -------------------------------------------------------------------------------- 1 | 策略模式:Strategy 2 | 3 | 该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。 4 | 策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。 5 | 6 | 7 | 主要优点如下: 8 | 1.多重条件语句不易维护,而使用策略模式可以避免使用多重条件语句。 9 | 2.策略模式提供了一系列的可供重用的算法族,恰当使用继承可以把算法族的公共代码转移到父类里面,从而避免重复的代码。 10 | 3.策略模式可以提供相同行为的不同实现,客户可以根据不同时间或空间要求选择不同的。 11 | 4.策略模式提供了对开闭原则的完美支持,可以在不修改原代码的情况下,灵活增加新算法。 12 | 5.策略模式把算法的使用放到环境类中,而算法的实现移到具体策略类中,实现了二者的分离。 13 | 14 | 主要缺点如下: 15 | 1.客户端必须理解所有策略算法的区别,以便适时选择恰当的算法类。 16 | 2.策略模式造成很多的策略类。 17 | 18 | 19 | 策略模式的主要角色如下。 20 | 1.抽象策略(Strategy)类:定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。 21 | 2.具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现。 22 | 3.环境(Context)类:持有一个策略类的引用,最终给客户端调用。 23 | 24 | 具体应用场景: 25 | 1.一个系统需要动态地在几种算法中选择一种时,可将每个算法封装到策略类中。 26 | 2.一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现,可将每个条件分支移入它们各自的策略类中以代替这些条件语句。 27 | 3.系统中各算法彼此完全独立,且要求对客户隐藏具体算法的实现细节时。 28 | 4.系统要求使用算法的客户不应该知道其操作的数据时,可使用策略模式来隐藏与算法相关的数据结构。 29 | 5.多个类只区别在表现行为不同,可以使用策略模式,在运行时动态选择具体要执行的行为。 30 | -------------------------------------------------------------------------------- /design_pattern/src/Strategy/Strategy.java: -------------------------------------------------------------------------------- 1 | package Strategy; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/15 下午3:02 6 | * File Description:抽象策略类 7 | */ 8 | public interface Strategy { 9 | public void strategyMethod(); 10 | } 11 | -------------------------------------------------------------------------------- /design_pattern/src/Strategy/StrategyTest.java: -------------------------------------------------------------------------------- 1 | package Strategy; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/15 下午3:37 6 | * File Description: 7 | */ 8 | public class StrategyTest { 9 | public static void main(String[] args) { 10 | Context context=new Context(); 11 | Strategy strategyA=new ConcreteStrategyA(); 12 | context.setStrategy(strategyA); 13 | context.strategyMethod(); 14 | System.out.println("-------------------"); 15 | 16 | Strategy strategyB=new ConcreteStrategyB(); 17 | context.setStrategy(strategyB); 18 | context.strategyMethod(); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /design_pattern/src/Strategy/Strategy_UML.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/src/Strategy/Strategy_UML.png -------------------------------------------------------------------------------- /design_pattern/src/TemplateMethod/AbstractClass.java: -------------------------------------------------------------------------------- 1 | package TemplateMethod; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/15 下午2:42 6 | * File Description:抽象类 7 | */ 8 | public abstract class AbstractClass { 9 | public void templateMethod(){ // 模板方法 10 | SpecialMethod(); 11 | abstractMethod1(); 12 | abstractMethod2(); 13 | } 14 | 15 | public void SpecialMethod(){ 16 | System.out.println("抽象类的具体方法被调用"); 17 | } 18 | 19 | public abstract void abstractMethod1(); //抽象方法1 20 | public abstract void abstractMethod2(); //抽象方法2 21 | } 22 | -------------------------------------------------------------------------------- /design_pattern/src/TemplateMethod/ConcreteClass.java: -------------------------------------------------------------------------------- 1 | package TemplateMethod; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/15 下午2:46 6 | * File Description:具体子类 7 | */ 8 | public class ConcreteClass extends AbstractClass{ 9 | public void abstractMethod1(){ 10 | System.out.println("抽象方法1的实现被调用..."); 11 | } 12 | public void abstractMethod2(){ 13 | System.out.println("抽象方法2的实现被调用..."); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /design_pattern/src/TemplateMethod/TemplateMethod: -------------------------------------------------------------------------------- 1 | 模板方法模式:TemplateMethod 2 | 3 | 定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。 4 | 它是一种类行为型模式。 5 | 6 | 主要优点如下: 7 | 1.它封装了不变部分,扩展可变部分。它把认为是不变部分的算法封装到父类中实现,而把可变部分算法由子类继承实现,便于子类继续扩展。 8 | 2.它在父类中提取了公共的部分代码,便于代码复用。 9 | 3.部分方法是由子类实现的,因此子类可以通过扩展方式增加相应的功能,符合开闭原则。 10 | 11 | 该模式的主要缺点如下: 12 | 1.对每个不同的实现都需要定义一个子类,这会导致类的个数增加,系统更加庞大,设计也更加抽象。 13 | 2.父类中的抽象方法由子类实现,子类执行的结果会影响父类的结果,这导致一种反向的控制结构,它提高了代码阅读的难度。 14 | 15 | 16 | 模板方法模式包含以下主要角色。 17 | 18 | (1) 抽象类(Abstract Class):负责给出一个算法的轮廓和骨架。它由一个模板方法和若干个基本方法构成。这些方法的定义如下。 19 | 20 | ① 模板方法:定义了算法的骨架,按某种顺序调用其包含的基本方法。 21 | 22 | ② 基本方法:是整个算法中的一个步骤,包含以下几种类型。 23 | 抽象方法:在抽象类中申明,由具体子类实现。 24 | 具体方法:在抽象类中已经实现,在具体子类中可以继承或重写它。 25 | 钩子方法:在抽象类中已经实现,包括用于判断的逻辑方法和需要子类重写的空方法两种。 26 | 27 | (2) 具体子类(Concrete Class):实现抽象类中所定义的抽象方法和钩子方法,它们是一个顶级逻辑的一个组成步骤 28 | 29 | 30 | 模板方法模式通常适用于以下场景: 31 | 1.算法的整体步骤很固定,但其中个别部分易变时,这时候可以使用模板方法模式,将容易变的部分抽象出来,供子类实现。 32 | 2.当多个子类存在公共的行为时,可以将其提取出来并集中到一个公共父类中以避免代码重复。首先,要识别现有代码中的不同之处,并且将不同之处分离为新的操作。最后,用一个调用这些新的操作的模板方法来替换这些不同的代码。 33 | 3.当需要控制子类的扩展时,模板方法只在特定点调用钩子操作,这样就只允许在这些点进行扩展。 34 | 35 | 36 | -------------------------------------------------------------------------------- /design_pattern/src/TemplateMethod/TemplateMethodTest.java: -------------------------------------------------------------------------------- 1 | package TemplateMethod; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/3/15 下午2:49 6 | * File Description:模板方法测试类 7 | */ 8 | public class TemplateMethodTest { 9 | public static void main(String[] args) { 10 | AbstractClass tm=new ConcreteClass(); 11 | tm.templateMethod(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /design_pattern/src/TemplateMethod/TemplateMethod_UML.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/design_pattern/src/TemplateMethod/TemplateMethod_UML.png -------------------------------------------------------------------------------- /offer/m03.java: -------------------------------------------------------------------------------- 1 | package offer; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/25 下午4:51 6 | * File Description:数组中重复的数字:在一个长度为 n 的数组 nums 里的所有数字都在 7 | * 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。 8 | * 请找出数组中任意一个重复的数字。 9 | * 10 | * 11 | * 如果没有重复数字,那么正常排序后,数字i应该在下标为i的位置,所以思路是重头扫描数组, 12 | * 遇到下标为i的数字如果不是i的话,(假设为m),那么我们就拿与下标m的数字交换。 13 | * 在交换过程中,如果有重复的数字发生,那么终止返回ture 14 | * 15 | */ 16 | public class m03 { 17 | public int findRepeatNumber(int[] nums) { 18 | int temp; 19 | for(int i=0;i stack=new Stack<>(); 16 | while(head!=null){ 17 | stack.push(head.val); 18 | // System.out.println(head.val); 19 | head=head.next; 20 | } 21 | int[] ans=new int[stack.size()]; 22 | int i=0; 23 | while(!stack.empty()){ 24 | // System.out.println(stack.peek()); 25 | ans[i++]=stack.pop(); 26 | } 27 | return ans; 28 | 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /offer/m09.java: -------------------------------------------------------------------------------- 1 | package offer; 2 | 3 | import java.util.Stack; 4 | 5 | /** 6 | * @author:Sun Hongwei 7 | * @2020/2/27 下午10:32 8 | * File Description:用两个栈实现队列: 用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 ) 9 | * 10 | * 11 | *删除队头元素: 若stack2为空,把stack1中的元素全部取出压入到stack2中即可 12 | */ 13 | public class m09 { 14 | class CQueue { 15 | private Stack stack1; //stack1用于储存元素 16 | private Stack stack2; //stack2用于辅助,操作删除队头元素 17 | 18 | public CQueue() { 19 | stack1=new Stack(); 20 | stack2=new Stack(); 21 | } 22 | 23 | public void appendTail(int value) { 24 | stack1.push(value); 25 | } 26 | 27 | public int deleteHead() { 28 | if(stack1.isEmpty() && stack2.isEmpty()){ 29 | return -1; 30 | } 31 | if(stack2.isEmpty()){ 32 | while (!stack1.isEmpty()){ 33 | stack2.push(stack1.pop()); 34 | } 35 | } 36 | return stack2.pop(); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /offer/m13.java: -------------------------------------------------------------------------------- 1 | package offer; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/28 上午9:53 6 | * File Description:机器人的运动范围:地上有一个m行n列的方格,从坐标[0,0]到坐标[m-1,n-1]。 7 | * 一个机器人从坐标[0, 0]的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外), 8 | * 也不能进入行坐标和列坐标的数位之和大于k的格子。 9 | * 10 | * 11 | * 深度优先遍历DFS 12 | */ 13 | public class m13 { 14 | private int m,n,k,count=0; 15 | private boolean[][] visited; 16 | public int movingCount(int m, int n, int k) { 17 | this.visited=new boolean[m][n]; //访问标志位 18 | this.m=m; 19 | this.k=k; 20 | this.n=n; 21 | dfs(0,0); 22 | return count; 23 | } 24 | public void dfs(int i,int j){ 25 | if(i<0 || i>=m || j<0 || j>=n || visited[i][j]==true){ 26 | return; 27 | }//遇到边界 28 | 29 | if((i%10+i/10)+(j%10+j/10)>k){ 30 | return; //数位之和超过预定值 31 | } 32 | visited[i][j]=true; 33 | count++; 34 | 35 | //遍历下一格 36 | dfs(i-1,j); 37 | dfs(i+1,j); 38 | dfs(i,j-1); 39 | dfs(i,j+1); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /offer/m17.java: -------------------------------------------------------------------------------- 1 | package offer; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/29 下午6:08 6 | * File Description:输入数字 n,按顺序打印出从 1 到最大的 n 位十进制数。 7 | * 比如输入 3,则打印出 1、2、3 一直到最大的 3 位数 999。 8 | * 9 | */ 10 | public class m17 { 11 | public int[] printNumbers(int n) { 12 | int num=(int)Math.pow(10,n)-1; 13 | int[] ans=new int[num]; 14 | for(int i=0;i=0 && nums[right]%2==0){ 20 | right--; 21 | } 22 | if(left>right) break; 23 | temp=nums[left]; 24 | nums[left]=nums[right]; 25 | nums[right]=temp; 26 | } 27 | return nums; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /offer/m26.java: -------------------------------------------------------------------------------- 1 | package offer; 2 | 3 | import java.util.Date; 4 | 5 | /** 6 | * @author:Sun Hongwei 7 | * @2020/2/28 下午6:58 8 | * File Description: 树的子结构: 输入两棵二叉树A和B,判断B是不是A的子结构。 9 | * (约定空树不是任意一个树的子结构) , B是A的子结构, 即 A中有出现和B相同的结构和节点值。 10 | * 11 | * 12 | * DFS+递归 13 | */ 14 | public class m26 { 15 | public boolean isSubStructure(TreeNode A, TreeNode B) { 16 | if(A==null || B==null) return false; 17 | //递归遍历,只要B是A,A的左子树或者右子树的子结构即可 18 | return DFS(A,B) || isSubStructure(A.left,B) || isSubStructure(A.right,B); 19 | 20 | } 21 | public boolean DFS(TreeNode A,TreeNode B){ 22 | if(B==null) return true; //B全部遍历完了,说明B是A的子结构 23 | if(A==null) return false; //B没有结束的情况下,A先结束了,所以B不是A的子结构 24 | 25 | return A.val==B.val && DFS(A.left,B.left) && DFS(A.right,B.right); 26 | 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /offer/m40.java: -------------------------------------------------------------------------------- 1 | package offer; 2 | 3 | import java.util.PriorityQueue; 4 | import java.util.Queue; 5 | 6 | /** 7 | * @author:Sun Hongwei 8 | * @2020/2/28 上午2:29 9 | * File Description:最小的k个数:输入整数数组 arr ,找出其中最小的 k 个数。 10 | * 例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。 11 | * 12 | * 13 | * Java中PirorityQueue以堆为基础 14 | */ 15 | public class m40 { 16 | public int[] getLeastNumbers(int[] arr, int k) { 17 | if(k==0) return new int[0]; 18 | Queue q=new PriorityQueue((a,b)->b-a); 19 | for(int a:arr){ 20 | if(q.size()a){ 23 | q.remove(); 24 | q.add(a); 25 | } 26 | } 27 | 28 | int[] result=new int[k]; 29 | int num=0; 30 | while(q.size()>0){ 31 | result[num++]=q.remove(); 32 | } 33 | return result; 34 | 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /offer/m45.java: -------------------------------------------------------------------------------- 1 | package offer; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * @author:Sun Hongwei 8 | * @2020/2/28 下午3:56 9 | * File Description:把数组排成最小的数: 输入一个正整数数组,把数组里所有数字拼接起来排成一个数, 10 | * 打印能拼接出的所有数字中最小的一个。 11 | * 12 | * 本质上就是排序题,根据字符串a+b和b+a的大小来排序 13 | * 这里用到了sort函数里套用compareTo 14 | * 15 | */ 16 | public class m45 { 17 | public String minNumber(int[] nums) { 18 | List str=new ArrayList(); 19 | //转换为String数组 20 | for(int n:nums){ 21 | str.add(String.valueOf(n)); 22 | } 23 | str.sort((s1,s2)->(s1+s2).compareTo(s2+s1)); 24 | StringBuilder stringBuilder=new StringBuilder(); 25 | for(String s:str){ 26 | stringBuilder.append(s); 27 | } 28 | return stringBuilder.toString(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /offer/m46.java: -------------------------------------------------------------------------------- 1 | package offer; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/28 下午6:27 6 | * File Description:把数字翻译成字符串:给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” , 7 | * 1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。一个数字可能有多个翻译。 8 | * 请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。 9 | * 10 | * 11 | * 12 | *动态规划:若第i位和第i-1位组成的数字小于26且大于等于10,那么dp[i]=dp[i-1]+dp[i-2] 13 | * 否则dp[i]=dp[i-1] 14 | */ 15 | public class m46 { 16 | public int translateNum(int num) { 17 | char[] numc=String.valueOf(num).toCharArray(); 18 | int[] dp=new int[numc.length]; 19 | if(numc.length==1) return 1; 20 | //确定动态转移方程前两位 21 | dp[0]=1; 22 | if((numc[0]-'0')*10+numc[1]-'0'<26){ 23 | dp[1]=2; 24 | }else{ 25 | dp[1]=1; 26 | } 27 | for(int i=2;i=10){ //某一位是0的情况也需要考虑 30 | dp[i]=dp[i-1]+dp[i-2]; 31 | }else{ 32 | dp[i]=dp[i-1]; 33 | } 34 | } 35 | return dp[numc.length-1]; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /offer/m47.java: -------------------------------------------------------------------------------- 1 | package offer; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/27 下午7:50 6 | * File Description:礼物的最大价值:在一个 m*n 的棋盘的每一格都放有一个礼物, 7 | * 每个礼物都有一定的价值(价值大于 0)。你可以从棋盘的左上角开始拿格子里的礼物, 8 | * 并每次向右或者向下移动一格、直到到达棋盘的右下角。给定一个棋盘及其上面的礼物的价值, 9 | * 请计算你最多能拿到多少价值的礼物? 10 | * 11 | * 动态规划:状态转移方程:dp[i][j]=max(dp[i-1][j],dp[i][j-1])+grid[i][j]; 12 | * 13 | */ 14 | public class m47 { 15 | public int maxValue(int[][] grid) { 16 | for(int i=1;i nodes=new ArrayList<>(); 17 | private int k; 18 | public int kthLargest(TreeNode root, int k) { 19 | this.k=k; 20 | inorder(root); 21 | return nodes.get(k-1); 22 | } 23 | 24 | private void inorder(TreeNode root){ 25 | if(root.right!=null) inorder(root.right); 26 | nodes.add(root.val); 27 | if(nodes.size()==k) return; 28 | if(root.left!=null) inorder(root.left); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /offer/m56_1.java: -------------------------------------------------------------------------------- 1 | package offer; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/25 下午9:08 6 | * File Description:数组中数字出现的次数:一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。 7 | * 请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。 8 | * 9 | * 10 | * !异或处理:相同的数字异或后,结果为0,不相同的数字处理后,结果不为0 11 | * 12 | * 1. 先把所有数字异或处理,找出结果不为1的那一位 13 | * 2. 按照那一位是0或者是1,把结果分为两组(这样两个答案一定都在不同组) 14 | * 3. 对每一组单独异或处理,找到每组的那个数 15 | * 16 | */ 17 | public class m56_1 { 18 | public int[] singleNumbers(int[] nums) { 19 | int ans=0; 20 | int[] result=new int[2]; 21 | for(int i:nums){ 22 | ans=ans^i; 23 | } 24 | int lastOne = ans & -ans; //求出结果是1的最后1位,其他位是0 25 | //将数组分为两组 26 | for(int i:nums){ 27 | if((i&lastOne)==0){ 28 | result[0]^=i; 29 | }else{ 30 | result[1]^=i; 31 | } 32 | } 33 | return result; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /offer/m56_2.java: -------------------------------------------------------------------------------- 1 | package offer; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/25 下午10:07 6 | * File Description:数组中数字出现的次数 II:在一个数组 nums 中除一个数字只出现一次之外,其他数字都出现了三次。 7 | * 请找出那个只出现一次的数字。 8 | * 9 | * 10 | * 所有数转化成二进制按位相加,出现三次的数相加之和每位都是三的倍数,取余数后即为只出现一次的数 11 | */ 12 | public class m56_2 { 13 | public int singleNumber(int[] nums) { 14 | int ans=0; 15 | for(int i=0;i<32;i++) { 16 | int count=0; //count用于计算每一位的和 17 | for(int n:nums){ 18 | if(((1<0){ //取第i位的值 19 | count++; 20 | } 21 | } 22 | if(count%3==1){ 23 | ans+=(1<target){ 18 | j--; 19 | }else if(nums[i]+nums[j]s.length()) return s; 17 | chars=s.toCharArray(); 18 | //翻转 19 | reverse(0,n-1); 20 | reverse(n,s.length()-1); 21 | reverse(0,s.length()-1); 22 | 23 | return new String(chars); 24 | } 25 | private void reverse(int i,int j){ 26 | char t; 27 | while(i0 && nums[i]-nums[i-1]>1 && nums[i-1]!=0) { 24 | if (nums[i]-nums[i-1]-1>count) { //如果0不够替代中间的差值,返回false 25 | return false; 26 | }else { 27 | count-=(nums[i]-nums[i-1]-1); 28 | } 29 | }else if(i>0 && nums[i]==nums[i-1]){ //如果遇到重复不为0的牌,直接返回false 30 | return false; 31 | } 32 | } 33 | return true; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /offer/m62.java: -------------------------------------------------------------------------------- 1 | package offer; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/25 下午6:01 6 | * File Description:圆圈中最后剩下的数字:0,1,...,n-1这n个数字排成一个圆圈, 7 | * 从数字0开始,每次从这个圆圈里删除第m个数字。求出这个圆圈里剩下的最后一个数字。 8 | * 9 | * 10 | */ 11 | public class m62 { 12 | public int lastRemaining(int n, int m) { 13 | if(n<1 || m<1){ 14 | return -1; 15 | } 16 | int ans=0; 17 | for(int i=2;i<=n;i++){ 18 | ans=(ans+m)%i; 19 | } 20 | return ans; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /offer/m64.java: -------------------------------------------------------------------------------- 1 | package offer; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/25 下午5:47 6 | * File Description: 求1+2+…+n:求 1+2+...+n , 7 | * 要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C) 8 | * 9 | * 10 | * 递归 11 | */ 12 | public class m64 { 13 | public int sumNums(int n) { 14 | return n==1?1:sumNums(n-1)+n; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /offer/m65.java: -------------------------------------------------------------------------------- 1 | package offer; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/28 上午10:29 6 | * File Description:不用加减乘除做加法 7 | * 8 | * 9 | * 位运算 10 | */ 11 | public class m65 { 12 | public int add(int a, int b) { 13 | int sum=0; 14 | while(b!=0){ 15 | sum=a^b; //异或:表示求各位数字之和,不考虑进位 16 | b=(a&b)<<1; //与运算,再向右移一位,表示求进位 17 | a=sum; 18 | } 19 | return sum; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /offer/m66.java: -------------------------------------------------------------------------------- 1 | package offer; 2 | 3 | /** 4 | * @author:Sun Hongwei 5 | * @2020/2/28 上午1:17 6 | * File Description:构建乘积数组: 给定一个数组 A[0,1,…,n-1],请构建一个数组 B[0,1,…,n-1], 7 | * 其中 B 中的元素 B[i]=A[0]×A[1]×…×A[i-1]×A[i+1]×…×A[n-1]。不能使用除法。 8 | * 9 | * 10 | * 将每个最终答案分成left*right两部分来看,分别从左和从右遍历两遍计算即可 11 | * 12 | */ 13 | public class m66 { 14 | public int[] constructArr(int[] a) { 15 | int[] result=new int[a.length]; 16 | int left=1,right=1; 17 | //求left 18 | for(int i=0;i=0;i--){ 24 | result[i]*=right; 25 | right*=a[i]; 26 | } 27 | return result; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /sorting/.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /workspace.xml -------------------------------------------------------------------------------- /sorting/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /sorting/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /sorting/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /sorting/out/production/sorting/BinarySearch.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/sorting/out/production/sorting/BinarySearch.class -------------------------------------------------------------------------------- /sorting/out/production/sorting/BubbleSort.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/sorting/out/production/sorting/BubbleSort.class -------------------------------------------------------------------------------- /sorting/out/production/sorting/BucketSort.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/sorting/out/production/sorting/BucketSort.class -------------------------------------------------------------------------------- /sorting/out/production/sorting/InsertSort.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/sorting/out/production/sorting/InsertSort.class -------------------------------------------------------------------------------- /sorting/out/production/sorting/MergeSort.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/sorting/out/production/sorting/MergeSort.class -------------------------------------------------------------------------------- /sorting/out/production/sorting/QuickSort.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/sorting/out/production/sorting/QuickSort.class -------------------------------------------------------------------------------- /sorting/out/production/sorting/ShellSort.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/sorting/out/production/sorting/ShellSort.class -------------------------------------------------------------------------------- /sorting/out/production/sorting/SortTest.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunhongwei815/my_leetcode_algorithm/b38088497d490ea03183d045c6095a5b5700715d/sorting/out/production/sorting/SortTest.class -------------------------------------------------------------------------------- /sorting/sorting.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /sorting/src/BinarySearch.java: -------------------------------------------------------------------------------- 1 | /** 2 | * @author:Sun Hongwei 3 | * @2020/3/12 上午1:23 4 | * File Description:二分查找 5 | */ 6 | public class BinarySearch { 7 | public static int binarySearch(int[] array,int num){ 8 | int l=0,r=array.length-1,mid; 9 | while(l<=r){ 10 | mid=(l+r)/2; 11 | if(array[mid] == num){ 12 | return mid; 13 | }else if(array[mid] < num){ 14 | l=mid+1; 15 | }else{ 16 | r=mid-1; 17 | } 18 | } 19 | return -1; //找不到返回-1 20 | } 21 | 22 | 23 | } 24 | -------------------------------------------------------------------------------- /sorting/src/BubbleSort.java: -------------------------------------------------------------------------------- 1 | /** 2 | * @author:Sun Hongwei 3 | * @2020/3/12 上午1:28 4 | * File Description:冒泡排序 5 | * 6 | * 7 | */ 8 | public class BubbleSort { 9 | public static int[] bubbleSort(int[] array){ 10 | //外层循环:排序的趟数 11 | for(int i=0;iarray[j+1]){ 17 | int temp=array[j+1]; 18 | array[j+1]=array[j]; 19 | array[j]=temp; 20 | } 21 | } 22 | } 23 | return array; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /sorting/src/InsertSort.java: -------------------------------------------------------------------------------- 1 | /** 2 | * @author:Sun Hongwei 3 | * @2020/3/12 上午2:00 4 | * File Description:插入排序 5 | * 6 | */ 7 | public class InsertSort { 8 | public static int[] insertSort(int[] array){ 9 | for(int i=1;i=0 && num=1){ 10 | shellInsertSort(array,dk); 11 | if(dk==1){ 12 | break; 13 | } 14 | dk=dk/3+1; 15 | } 16 | return array; 17 | } 18 | 19 | private static void shellInsertSort(int[] array,int dk){ 20 | //每次步长为dk的插入排序 21 | for(int i=dk;i=0 && num