├── .gitignore ├── CLRS └── elementary-ds │ ├── QueueFixedSize.java │ ├── StackFixedSize.java │ └── run.sh ├── GTG ├── README.md └── ch3 │ └── 1 │ ├── Scoreboard-INPUT.txt │ └── Scoreboard.java ├── LICENSE ├── README.md ├── algorithms ├── Mathematics │ ├── README.md │ └── java │ │ └── FastPower.java ├── The Inversions Problem │ ├── README.md │ └── java │ │ ├── FastCounter.java │ │ ├── InversionsCounter.java │ │ └── SlowCounter.java ├── The Maximum-Subarray Problem │ ├── README.md │ └── java │ │ ├── LogarithmicSolution.java │ │ ├── MaxSubArrayFinder.java │ │ └── NaiveSolution.java ├── The Searching Problem │ ├── README.md │ └── java │ │ ├── BinarySearch.java │ │ ├── LinearSearch.java │ │ └── SearchingAlg.java ├── The Selection Problem │ └── README.md └── The Sorting Problem │ ├── README.md │ └── java │ ├── InsertionSort.java │ ├── MergeSort.java │ ├── QuickSortClassic.java │ ├── QuickSortMedian.java │ ├── QuickSortRandomized.java │ ├── QuickSortRandomizedMedian.java │ ├── SelectionSort.java │ └── SortingAlg.java ├── out-of-date ├── PROBLEMS.md ├── cpp │ ├── datastructures │ │ └── priority_queue.cpp │ ├── samples │ │ └── rmq_demo.cpp │ ├── searching │ │ └── rmq.cpp │ └── sorting │ │ ├── heap_sort.cpp │ │ └── test_heap.txt └── java │ ├── QuickFind.java │ ├── UnionFind.java │ └── WeightedQuickUnion.java └── training ├── CoinChangeProblem.java ├── FibModulus.java ├── Fibonacci.java ├── Fibonacci.txt ├── GCD.java ├── GCD.txt ├── LCM.java ├── MaxPairwiseProduct.java ├── MaxPairwiseProduct.txt ├── README.md ├── Sum.java ├── Sum.txt ├── greedy ├── CoinChange.java └── FractionalKnapsack.java └── judge.sh /.gitignore: -------------------------------------------------------------------------------- 1 | # Java files 2 | *.class 3 | 4 | # VIm files 5 | *.swp 6 | 7 | # Compiled Object files 8 | *.slo 9 | *.lo 10 | *.o 11 | *.exe 12 | 13 | # Compiled Dynamic libraries 14 | *.so 15 | *.dylib 16 | 17 | # Compiled Static libraries 18 | *.lai 19 | *.la 20 | *.a 21 | -------------------------------------------------------------------------------- /CLRS/elementary-ds/QueueFixedSize.java: -------------------------------------------------------------------------------- 1 | import java.lang.StringBuilder; 2 | 3 | class Main { 4 | 5 | static class QueueFixedSize { 6 | private Object[] elements; 7 | private int tail, head, n; 8 | 9 | QueueFixedSize(int initialCapacity) { 10 | if (initialCapacity < 1) 11 | throw new RuntimeException("Initial capacity must be greater than zero"); 12 | this.elements = new Object[initialCapacity]; 13 | } 14 | 15 | void enqueue(E element) { 16 | this.elements[this.tail] = element; 17 | this.tail = (this.tail + 1) % this.elements.length; 18 | n++; 19 | } 20 | 21 | E dequeue() { 22 | @SuppressWarnings("unchecked") 23 | E element = (E) this.elements[this.head]; 24 | 25 | this.elements[this.head] = null; 26 | this.head = (this.head + 1) % this.elements.length; 27 | n--; 28 | 29 | return element; 30 | } 31 | 32 | @Override 33 | public String toString() { 34 | StringBuilder str = new StringBuilder("Q: "); 35 | for (int i = 0; i < n; i++) { 36 | str.append(this.elements[(this.head + i) % this.elements.length]).append(" "); 37 | } 38 | return str.toString(); 39 | } 40 | } 41 | 42 | public static void main(String[] args) { 43 | QueueFixedSize Q = new QueueFixedSize<>(5); 44 | System.out.println(Q); 45 | 46 | Q.enqueue(3); 47 | Q.enqueue(4); 48 | Q.enqueue(8); 49 | Q.enqueue(10); 50 | Q.enqueue(20); 51 | System.out.println(Q); 52 | 53 | System.out.println(Q.dequeue()); 54 | System.out.println(Q.dequeue()); 55 | System.out.println(Q); 56 | 57 | Q.enqueue(3); 58 | Q.enqueue(4); 59 | System.out.println(Q); 60 | 61 | for (int i = 0; i < 5; i++) { 62 | System.out.println(Q.dequeue()); 63 | System.out.println(Q.dequeue()); 64 | System.out.println(Q.dequeue()); 65 | Q.enqueue((i + 1) * 100); 66 | Q.enqueue((i + 2) * 100); 67 | Q.enqueue((i + 3) * 100); 68 | System.out.println(Q); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /CLRS/elementary-ds/StackFixedSize.java: -------------------------------------------------------------------------------- 1 | import java.lang.StringBuilder; 2 | 3 | /* 4 | * Chapter 10.1 - Elementary Data Structures: Stacks and Queues 5 | * Compile and run: javac StackFixedSize.java && java Main 6 | * 7 | * Author: Jeanderson Candido 8 | */ 9 | class Main { 10 | 11 | /* 12 | * Elementary implementation of Stack using a fixed-size array 13 | */ 14 | static class StackFixedSize { 15 | private Object[] elements; 16 | private int top; // This index holds the position of the next element to be removed 17 | 18 | StackFixedSize(int initialCapacity) { 19 | if (initialCapacity < 1) 20 | throw new RuntimeException("Initial capacity must be a positive integer greater than 0"); 21 | this.elements = new Object[initialCapacity]; 22 | this.top = -1; 23 | } 24 | 25 | void push(E element) { 26 | if (this.top == this.elements.length - 1) 27 | throw new RuntimeException("Reached maximum capacity!"); 28 | this.elements[++this.top] = element; 29 | } 30 | 31 | E pop() { 32 | if (isEmpty()) 33 | throw new RuntimeException("Empty stack!"); 34 | 35 | // This suppressing is safe since the implementation guarantees 36 | // that array "elements" contains only elements of type E (see "push") 37 | @SuppressWarnings("unchecked") 38 | E element = (E) this.elements[this.top]; 39 | 40 | this.elements[this.top--] = null; 41 | return element; 42 | } 43 | 44 | @Override 45 | public String toString() { 46 | StringBuilder str = new StringBuilder("["); 47 | for (int i = 0; i < this.top; i++) { 48 | str.append(elements[i]).append(", "); 49 | } 50 | if (this.top > -1) { 51 | str.append("top=").append(elements[this.top]); 52 | } 53 | return str.append("]").toString(); 54 | } 55 | 56 | boolean isEmpty() { 57 | return this.top < 0; 58 | } 59 | } 60 | 61 | public static void main(String[] args) { 62 | // Example from Figure 10.1 63 | StackFixedSize S = new StackFixedSize<>(7); 64 | 65 | S.push(15); 66 | S.push(6); 67 | S.push(2); 68 | S.push(9); 69 | System.out.println(S); 70 | 71 | S.push(17); 72 | S.push(3); 73 | System.out.println(S); 74 | 75 | System.out.println(S.pop()); 76 | System.out.println(S); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /CLRS/elementary-ds/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | javac $1 && java Main 3 | -------------------------------------------------------------------------------- /GTG/README.md: -------------------------------------------------------------------------------- 1 | * Book: Data Structures & Algorithms in Java 6th 2 | * Authors: 3 | * Michael GOODRICH 4 | * Roberto TAMASSIA 5 | * Michael GOLDWASSER 6 | 7 | -------------------------------------------------------------------------------- /GTG/ch3/1/Scoreboard-INPUT.txt: -------------------------------------------------------------------------------- 1 | 1 2 | 5 12 3 | + Jon 100 4 | + Aegon 90 5 | + Tyrion 220 6 | + Sansa 20 7 | + Littlefinger 50 8 | + Ned 80 9 | + Jamie 50 10 | + Robert 51 11 | - 1 12 | - 3 13 | - 3 14 | - 1 15 | -------------------------------------------------------------------------------- /GTG/ch3/1/Scoreboard.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedInputStream; 2 | import java.util.Scanner; 3 | 4 | /* 5 | * Implementation based on the scoreboard problem from Sec 3.1 6 | * 7 | * Author: Jeanderson Candido 8 | */ 9 | class Main { 10 | 11 | static class GameEntry { 12 | private String player; 13 | private int score; 14 | public GameEntry(String player, int score) { 15 | this.player = player; 16 | this.score = score; 17 | } 18 | public int getScore() { return this.score; } 19 | public String getPlayer() { return this.player; } 20 | 21 | @Override 22 | public String toString() { 23 | return String.format("%s - %d", getPlayer(), getScore()); 24 | } 25 | } 26 | static class Scoreboard { 27 | private GameEntry[] scores; 28 | private int entries; 29 | public Scoreboard(int capacity) { 30 | this.scores = new GameEntry[capacity]; 31 | this.entries = 0; 32 | } 33 | public void insert(GameEntry entry) { 34 | int newScore = entry.getScore(); 35 | if (entries < scores.length || newScore > scores[scores.length - 1].getScore()) { 36 | if (entries < scores.length) 37 | entries++; 38 | int pos = entries - 1; 39 | while (pos > 0 && newScore > scores[pos - 1].getScore()) { 40 | scores[pos] = scores[pos - 1]; 41 | pos--; 42 | } 43 | scores[pos] = entry; 44 | } 45 | } 46 | // Elements are indexed by one 47 | public GameEntry remove(int i) { 48 | GameEntry removed = null; 49 | if (i > 0 && i <= entries) { 50 | removed = scores[i - 1]; 51 | for (int pos = i; pos < entries; pos++) 52 | scores[pos - 1] = scores[pos]; 53 | scores[--entries] = null; 54 | } 55 | return removed; 56 | } 57 | @Override 58 | public String toString() { 59 | StringBuilder str = new StringBuilder("Scoreboard\n"); 60 | GameEntry entry = null; 61 | for (int i = 0; i < this.entries; i++) { 62 | entry = this.scores[i]; 63 | str.append(String.format("%3d - %s\n", entry.getScore(), entry.getPlayer())); 64 | } 65 | return str.toString(); 66 | } 67 | } 68 | 69 | public static void main(String[] args) { 70 | Scanner in = new Scanner(new BufferedInputStream(System.in)); 71 | int testcases = in.nextInt(); 72 | while (testcases-- > 0) { 73 | int capacity = in.nextInt(); 74 | int entries = in.nextInt(); 75 | 76 | Scoreboard scoreboard = new Scoreboard(capacity); 77 | for (int e = 0; e < entries; e++) { 78 | String op = in.next(); 79 | if ("+".equals(op)) { 80 | String player = in.next(); 81 | int score = in.nextInt(); 82 | scoreboard.insert(new GameEntry(player, score)); 83 | } else if ("-".equals(op)) { 84 | System.out.println(scoreboard.remove(in.nextInt())); 85 | } 86 | System.out.println(scoreboard); 87 | } 88 | } 89 | in.close(); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | data structures and algorithms 294 | Copyright (C) 2013 Jeanderson Barros Candido 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | {signature of Ty Coon}, 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Algorithms and Data Structures 2 | ============================== 3 | 4 | *"With advanced libraries and languages, you can accomplish some tasks without knowing Algorithms and Data Structures, but you can do much more with such knowledge. This is the bound between programmers and novices."* (Robert Sedgewick - Algorithms Part 1) 5 | 6 | ## About 7 | I created this repository to practice more the subject. As I'm studying, I implement problems and algorithms and push them here. 8 | 9 | Algorithms are organized by subjects (e.g. Searching, Sorting, etc...). For each problem, I create a common interface and have 10 | different classes implementing the problem's interface. I designed the classes to be concise and to provide enough information 11 | so you don't have to check any other files. Therefore, expect to see some duplicated code. The main concern here, is mastering 12 | the art of computer programming. 13 | 14 | I hope you find the information here useful for you. 15 | 16 | ## Contributing 17 | I decided to put my code here for a reason: Learning is more fun when we work together, right? Contributions are always 18 | welcomed. Please, if you find anything wrong (e.g. bugs or wrong information), consider the following steps: 19 | 20 | 1. [Open a new Issue](https://github.com/jeandersonbc/algorithms-and-ds/issues/new) describing the problem 21 | 2. [Fork](https://github.com/jeandersonbc/algorithms-and-ds/fork) this project :) 22 | 3. Fix the problem 23 | 4. Add your name on the Copyright header of each modified file 24 | 5. Submit a pull request (details [here](https://help.github.com/articles/using-pull-requests/#sending-the-pull-request)) 25 | 26 | ### Guidelines 27 | 28 | * Tab x Space: 29 | * Please, consider replacing tabs for blank spaces. 30 | 31 | * Updating the copyright header: 32 | * Add your information, respecting the indentation (see the example below) 33 | ``` 34 | Contributors: 35 | Jeanderson Candido - Issue #8 36 | FirstName LastName - Issue #id 37 | ``` 38 | * Committing changes: 39 | ``` 40 | Issue #id - Issue Title 41 | 42 | Brief description of what your work 43 | ``` 44 | 45 | I know. Easy, right? :) 46 | 47 | ##References## 48 | * Books 49 | 50 | * [Introduction to Algorithms 3rd Edition]() - Cormen *et. al.* (aka CLRS) 51 | * [Algorithms 4th Edition]() - Robert Sedgewick and Kevin Wayne (SW) 52 | 53 | * Online Classes 54 | 55 | * Stanford University (by Tim Roughgarden) 56 | * [Algorithms: Design and Analysis, Part 1](https://www.coursera.org/course/algo) 57 | * [Algorithms: Design and Analysis, Part 2](https://www.coursera.org/course/algo2) 58 | 59 | * Princenton University (by R. Sedgewick and K. Wayne) 60 | * [Algorithms Part 1](https://www.coursera.org/course/algs4partI) 61 | * [Algorithms Part 2](https://www.coursera.org/course/algs4partII) 62 | -------------------------------------------------------------------------------- /algorithms/Mathematics/README.md: -------------------------------------------------------------------------------- 1 | Mathematics 2 | =========== 3 | 4 | Math algorithms. 5 | 6 | ###Summary:### 7 | * "FastPower" - Computing `a^b` in logarithmic time 8 | -------------------------------------------------------------------------------- /algorithms/Mathematics/java/FastPower.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013, 2014 Jeanderson Barros Candido 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | * 18 | * Contributors: 19 | * Jeanderson Candido - Initial Implementation 20 | */ 21 | import java.lang.Math; 22 | 23 | public class FastPower { 24 | 25 | /** Returns a^b in log(b) time */ 26 | static long fastPow(long a, long b) { 27 | if (b < 0) 28 | throw new java.lang.UnsupportedOperationException("B must be greater or equals to zero."); 29 | if (b == 0) 30 | return 1; 31 | if (b == 1) 32 | return a; 33 | 34 | long c = a * a; 35 | long result = fastPow(c, b >> 1); 36 | 37 | return ((b & 1) == 1) ? result * a : result; 38 | } 39 | // Sanity check with Math.pow 40 | public static void main(String[] args) { 41 | 42 | // for M > 15, we start to miss precision 43 | // and results diverge 44 | long M = 15; 45 | for (long i = 0; i < M; i++) { 46 | for (long j = 0; j < M; j++) { 47 | 48 | long result = fastPow(i, j); 49 | long expected = (long) Math.pow(i, j); 50 | 51 | if (result != expected) { 52 | throw new java.lang.RuntimeException( 53 | String.format("(a:%d, b:%d) Expected: %d\tResult: %d", 54 | i, j, expected, result 55 | ) 56 | ); 57 | } 58 | } 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /algorithms/The Inversions Problem/README.md: -------------------------------------------------------------------------------- 1 | The Inversions Problem 2 | ====================== 3 | 4 | How to count the number of inversions in a sequence of values? 5 | 6 | Given a sequence `A` of integers, an **inversion** is a pair `(A[i], A[j])` 7 | such that `A[i]` is greater than `A[j]` and `i` is less than `j` for all `i` and 8 | `j` in `A[1...n]` 9 | 10 | ###Input:### 11 | Sequence of `N` numbers `A = [a1, a2, a3, ..., aN]` 12 | 13 | ####Output:#### 14 | An integer representing the number of inversions in `A` 15 | 16 | ###Example:### 17 | * `A = [3,2,4]` 18 | * `f(A) = 1` 19 | 20 | ##Reference:## 21 | * CLRS 3rd Edition - Problem 2-4 22 | -------------------------------------------------------------------------------- /algorithms/The Inversions Problem/java/FastCounter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013, 2014 Jeanderson Barros Candido 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | * 18 | * Contributors: 19 | * Jeanderson Candido - Initial Implementation 20 | */ 21 | import java.lang.Comparable; 22 | import java.util.List; 23 | import java.util.ArrayList; 24 | /** 25 | * The FastCounter solution uses a Divide and Conquer approach. 26 | * 27 | * Characteristics: 28 | * Running time: Linear-Logarithmic BigOh(N * log(N)) 29 | * Requires extra memory (not in-place). It is a modification of the 30 | * Merge-Sort algorithm. 31 | * 32 | * Recurrence Function: 33 | * T(n) = 2T(n / 2) + O(n) 34 | */ 35 | public class FastCounter> implements InversionsCounter { 36 | 37 | private List buffer; 38 | 39 | @Override 40 | public int count(List elements) { 41 | if (elements == null) 42 | return 0; 43 | 44 | this.buffer = new ArrayList(elements.size()); 45 | int total = count(elements, 0, elements.size() - 1); 46 | this.buffer = null; 47 | 48 | return total; 49 | } 50 | private int count(List elements, int min, int max) { 51 | int total = 0; 52 | if (min == max) 53 | return total; 54 | 55 | int mid = (min + max) >> 1; 56 | total += count(elements, min, mid); 57 | total += count(elements, mid + 1, max); 58 | 59 | if (isLessThanOrEqualsTo(elements.get(mid), elements.get(mid + 1))) 60 | return total; 61 | 62 | for (int k = min; k <= max; k++) { 63 | this.buffer.add(k, elements.get(k)); 64 | } 65 | int left = min; 66 | int right = mid + 1; 67 | for (int k = min; k <= max; k++) { 68 | if (left > mid) 69 | elements.set(k, this.buffer.get(right++)); 70 | else if (right > max) 71 | elements.set(k, this.buffer.get(left++)); 72 | else if (isLessThanOrEqualsTo(this.buffer.get(left), this.buffer.get(right))) 73 | elements.set(k, this.buffer.get(left++)); 74 | else { 75 | total += mid - left + 1; 76 | elements.set(k, this.buffer.get(right++)); 77 | } 78 | } 79 | return total; 80 | } 81 | private boolean isLessThanOrEqualsTo(T first, T second) { 82 | return (first.compareTo(second) <= 0); 83 | } 84 | 85 | // Simple driver 86 | public static void main(String[] args) { 87 | InversionsCounter alg = new FastCounter(); 88 | List invertedSequence = new ArrayList(); 89 | for (int e = 10000; e >= 1; e--) { 90 | invertedSequence.add(e); 91 | } 92 | int result = alg.count(invertedSequence); 93 | int expectedResult = 49995000; 94 | if (result != expectedResult) { 95 | throw new java.lang.RuntimeException( 96 | String.format("Result should be equals to %d: %d", 97 | expectedResult, result) 98 | ); 99 | } 100 | System.out.println("All tests passed."); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /algorithms/The Inversions Problem/java/InversionsCounter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013, 2014 Jeanderson Barros Candido 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | * 18 | * Contributors: 19 | * Jeanderson Candido - Initial Implementation 20 | */ 21 | import java.util.List; 22 | import java.lang.Comparable; 23 | /** 24 | * Interface for the problem. 25 | */ 26 | public interface InversionsCounter> { 27 | 28 | /** 29 | * Returns the number of inversions in elements. 30 | */ 31 | int count(List elements); 32 | 33 | } 34 | -------------------------------------------------------------------------------- /algorithms/The Inversions Problem/java/SlowCounter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013, 2014 Jeanderson Barros Candido 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | * 18 | * Contributors: 19 | * Jeanderson Candido - Initial Implementation 20 | */ 21 | import java.lang.Comparable; 22 | import java.util.List; 23 | import java.util.ArrayList; 24 | /** 25 | * The SlowCounter solution uses an incremental approach. 26 | * 27 | * Characteristics: 28 | * Running time: Quadratic BigOh(N^2) 29 | * It is an in-place solution based on the Insertion Sort algorithm. 30 | */ 31 | public class SlowCounter> implements InversionsCounter { 32 | 33 | @Override 34 | public int count(List elements) { 35 | int total = 0; 36 | if (elements == null) 37 | return total; 38 | for (int pos = 1; pos < elements.size(); pos++) { 39 | T key = elements.get(pos); 40 | int backwards = pos - 1; 41 | while (backwards >= 0 && isLessThan(key, elements.get(backwards))) { 42 | elements.set(backwards + 1, elements.get(backwards--)); 43 | total++; 44 | } 45 | elements.set(backwards + 1, key); 46 | } 47 | return total; 48 | } 49 | private boolean isLessThan(T first, T second) { 50 | return (first.compareTo(second) < 0); 51 | } 52 | 53 | // Simple driver 54 | public static void main(String[] args) { 55 | InversionsCounter alg = new SlowCounter(); 56 | List invertedSequence = new ArrayList(); 57 | for (int e = 10000; e >= 1; e--) { 58 | invertedSequence.add(e); 59 | } 60 | int result = alg.count(invertedSequence); 61 | int expectedResult = 49995000; 62 | if (result != expectedResult) { 63 | throw new java.lang.RuntimeException( 64 | String.format("Result should be equals to %d: %d", 65 | expectedResult, result) 66 | ); 67 | } 68 | System.out.println("All tests passed."); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /algorithms/The Maximum-Subarray Problem/README.md: -------------------------------------------------------------------------------- 1 | The Maximum-Subarray Problem 2 | ============================ 3 | 4 | Given a sequence `A` of `N` positive and negative integers, determine an `i` and 5 | `j` such that `1 <= i <= j <= N` and the sum of integers in the range `[i, j]` 6 | is the maximum possible sum 7 | 8 | ###Example:### 9 | * `A = [13, -3, -25, 20, -3, -16, -23, *18, 20, -7, 12*, -5, -22, 15, -4, 7]` 10 | * `f(A) = (8, 11)` 11 | 12 | ##Reference:## 13 | * CLRS 3d Edition - Section 4.1 14 | -------------------------------------------------------------------------------- /algorithms/The Maximum-Subarray Problem/java/LogarithmicSolution.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013, 2014 Jeanderson Barros Candido 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | * 18 | * Contributors: 19 | * Jeanderson Candido - Initial Implementation 20 | */ 21 | import java.util.List; 22 | 23 | public class LogarithmicSolution implements MaxSubArrayFinder { 24 | 25 | private int sum; 26 | 27 | public LogarithmicSolution(List values) { 28 | if (values == null) 29 | throw new java.lang.IllegalArgumentException("Parameter values should not be null"); 30 | 31 | this.sum = solve(values, 0, values.size() - 1); 32 | } 33 | private int solve(List values, int left, int right) { 34 | if (left == right) 35 | return values.get(left); 36 | 37 | int mid = (left + right) >> 1; 38 | int leftSum = solve(values, left, mid); 39 | int rightSum = solve(values, mid + 1, right); 40 | int crossingSum = solve(values, left, mid, right); 41 | 42 | if (leftSum > rightSum && leftSum > crossingSum) 43 | return leftSum; 44 | if (rightSum > leftSum && rightSum > crossingSum) 45 | return rightSum; 46 | return crossingSum; 47 | } 48 | private int solve(List values, int left, int mid, int right) { 49 | int total = values.get(mid); 50 | int partialSum = total; 51 | for (int i = mid - 1; i >= left; i--) { 52 | partialSum += values.get(i); 53 | if (partialSum > total) 54 | total = partialSum; 55 | } 56 | partialSum = total; 57 | for (int i = mid + 1; i <= right; i++) { 58 | partialSum += values.get(i); 59 | if (partialSum > total) 60 | total = partialSum; 61 | } 62 | return total; 63 | } 64 | @Override 65 | public int getMaxSum() { 66 | return this.sum; 67 | } 68 | // To make code simpler, I will not consider the following contracts 69 | @Override 70 | public int getRight() { 71 | throw new java.lang.UnsupportedOperationException("Not implemented"); 72 | } 73 | @Override 74 | public int getLeft() { 75 | throw new java.lang.UnsupportedOperationException("Not implemented"); 76 | } 77 | // Sanity check 78 | public static void main(String[] args) { 79 | List values = java.util.Arrays.asList( 80 | 13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7 81 | ); 82 | int expectedSum= 43; 83 | 84 | MaxSubArrayFinder alg = new LogarithmicSolution(values); 85 | test(expectedSum, alg.getMaxSum()); 86 | } 87 | static void test(int expected, int current) { 88 | if (current != expected) { 89 | throw new java.lang.RuntimeException( 90 | String.format("Expected %d but got %d", expected, current) 91 | ); 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /algorithms/The Maximum-Subarray Problem/java/MaxSubArrayFinder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013, 2014 Jeanderson Barros Candido 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | * 18 | * Contributors: 19 | * Jeanderson Candido - Initial Implementation 20 | */ 21 | import java.util.List; 22 | 23 | public interface MaxSubArrayFinder { 24 | 25 | /** 26 | * Returns the maximum sum from the maximum-subarray within values 27 | */ 28 | int getMaxSum(); 29 | 30 | /** 31 | * Returns the last index of the maximum-subarray within values 32 | */ 33 | int getRight(); 34 | 35 | /** 36 | * Returns the first index of the maximum-subarray within values 37 | */ 38 | int getLeft(); 39 | } 40 | -------------------------------------------------------------------------------- /algorithms/The Maximum-Subarray Problem/java/NaiveSolution.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013, 2014 Jeanderson Barros Candido 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | * 18 | * Contributors: 19 | * Jeanderson Candido - Initial Implementation 20 | */ 21 | import java.util.List; 22 | 23 | public class NaiveSolution implements MaxSubArrayFinder { 24 | 25 | private int left; 26 | private int right; 27 | private int sum; 28 | 29 | public NaiveSolution(List values) { 30 | if (values == null) 31 | throw new java.lang.IllegalArgumentException("Parameter values should not be null"); 32 | 33 | solve(values); 34 | } 35 | /** 36 | * This solution tests every single possible subarray A[i..j] for i less than 37 | * or equals to j. Therefore, it is not difficult to see that we have a solution bounded 38 | * by N squared. More strictly, it would not be exactly N squared because as i increases, 39 | * j decreases but it is okay since we are talking about BigOh-notation. 40 | */ 41 | private void solve(List values) { 42 | this.sum= values.get(0); 43 | for (int i = 0; i < values.size(); i++) { 44 | int maxTmp = values.get(i); 45 | for (int j = i + 1; j < values.size(); j++) { 46 | maxTmp += values.get(j); 47 | if (maxTmp > this.sum) { 48 | this.sum= maxTmp; 49 | this.right = j; 50 | this.left = i; 51 | } 52 | } 53 | } 54 | } 55 | @Override 56 | public int getMaxSum() { 57 | return this.sum; 58 | } 59 | @Override 60 | public int getRight() { 61 | return this.right; 62 | } 63 | @Override 64 | public int getLeft() { 65 | return this.left; 66 | } 67 | // Sanity check 68 | public static void main(String[] args) { 69 | List values = java.util.Arrays.asList( 70 | 13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7 71 | ); 72 | int expectedRight = 10; 73 | int expectedLeft = 7; 74 | int expectedSum= 43; 75 | 76 | MaxSubArrayFinder alg = new NaiveSolution(values); 77 | test(expectedRight, alg.getRight()); 78 | test(expectedSum, alg.getMaxSum()); 79 | test(expectedLeft, alg.getLeft()); 80 | } 81 | static void test(int expected, int current) { 82 | if (current != expected) { 83 | throw new java.lang.RuntimeException( 84 | String.format("Expected %d but got %d", expected, current) 85 | ); 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /algorithms/The Searching Problem/README.md: -------------------------------------------------------------------------------- 1 | The Searching Problem 2 | ===================== 3 | 4 | ####Input#### 5 | Sequence of `n` numbers `A = [a1, a2, a3, an]` and a value `V` 6 | 7 | ####Output#### 8 | An index `i` such that `V = A[i]` or `NIL` if `V` doesn't exist in `A` 9 | 10 | ####Example#### 11 | * `A=[1,2,3,4,5,4]` 12 | * `V=3` 13 | * `f(A, V) = 2` (considering 0 as the first index) 14 | 15 | ##Reference## 16 | * CLRS 3rd Edition - Problem 2.1-3 17 | -------------------------------------------------------------------------------- /algorithms/The Searching Problem/java/BinarySearch.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013, 2014 Jeanderson Barros Candido 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | * 18 | * Contributors: 19 | * Jeanderson Candido - Initial Implementation 20 | */ 21 | import java.util.List; 22 | import java.lang.Comparable; 23 | /** 24 | * The Binary Search algorithm uses a Divide and Conquer approach. 25 | * 26 | * Characteristics: 27 | * Running time: Logarithmic BigOh(log(n)) 28 | * It works by looking at the mid point of an ORDERED sequence and discarding the useless half 29 | * 30 | * Recurrence Function: 31 | * T(n) = T(n / 2) + O(1) 32 | * 33 | * Reference: 34 | * CLRS 3rd Edition - Problem 2.3-5 35 | */ 36 | public class BinarySearch> implements SearchingAlg { 37 | 38 | @Override 39 | public int indexOf(List elements, T target) { 40 | if (elements == null || target == null) 41 | return NIL; 42 | return indexOf(elements, target, 0, elements.size() - 1); 43 | } 44 | private int indexOf(List elements, T target, int min, int max) { 45 | if (min <= max) { 46 | int mid = (max + min) >> 1; 47 | if (elements.get(mid).equals(target)) 48 | return mid; 49 | if (isLessThan(elements.get(mid), target)) 50 | return indexOf(elements, target, mid + 1, max); 51 | return indexOf(elements, target, min, mid - 1); 52 | } 53 | return NIL; 54 | } 55 | private boolean isLessThan(T first, T second) { 56 | return (first.compareTo(second) < 0); 57 | } 58 | // sanity check 59 | public static void main(String[] args) { 60 | List data = new java.util.ArrayList(); 61 | for (int i = 0; i < 100; i++) 62 | data.add(i); 63 | SearchingAlg alg = new BinarySearch(); 64 | for (int i = 0; i < data.size(); i++) { 65 | int result = alg.indexOf(data, i); 66 | if (result == NIL) 67 | throw new java.lang.RuntimeException("Result shouldn't be NIL"); 68 | 69 | // necessary, otherwise List.remove(int index) will be called 70 | data.remove(new Integer(i)); 71 | 72 | result = alg.indexOf(data, i); 73 | if (result != NIL) 74 | throw new java.lang.RuntimeException("Result should be NIL"); 75 | } 76 | System.out.println("All tests passed."); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /algorithms/The Searching Problem/java/LinearSearch.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013, 2014 Jeanderson Barros Candido 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | * 18 | * Contributors: 19 | * Jeanderson Candido - Initial Implementation 20 | */ 21 | import java.util.List; 22 | import java.util.Arrays; 23 | /** 24 | * The LinearSearch algorithm uses an incremental approach. 25 | * 26 | * Characteristics: 27 | * Running-time: Linear - BigOh(n) 28 | * Works on unsorted sequences 29 | * 30 | * Loop invariant: 31 | * Target will never be in elements[0..i-1]. If the i-th is 32 | * the target element, the index i will be returned, breaking 33 | * the loop. If the loop terminates, it means that target 34 | * doesn't exist in elements. 35 | * 36 | * Reference: 37 | * CLRS 3rd Edition - Exercise 2.1-3 38 | */ 39 | public class LinearSearch implements SearchingAlg { 40 | 41 | @Override 42 | public int indexOf(List elements, T target) { 43 | if (elements != null && target != null) { 44 | for (int i = 0; i < elements.size(); i++) { 45 | if (target.equals(elements.get(i))) 46 | return i; 47 | } 48 | } 49 | return NIL; 50 | } 51 | 52 | // sanity check 53 | public static void main(String[] args) { 54 | List data = java.util.Arrays.asList(9,4,6,2,4,6,1,6,7,-1); 55 | int[] expectedIndexes = {0,1,2,3,1,2,6,2,8,9}; 56 | SearchingAlg alg = new LinearSearch(); 57 | for (int i = 0; i < data.size(); i++) { 58 | int result = alg.indexOf(data, data.get(i)); 59 | if (result == NIL) 60 | throw new java.lang.RuntimeException("Result shouldn't be NIL"); 61 | } 62 | System.out.println("All tests passed."); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /algorithms/The Searching Problem/java/SearchingAlg.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013, 2014 Jeanderson Barros Candido 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | * 18 | * Contributors: 19 | * Jeanderson Candido - Initial Implementation 20 | */ 21 | import java.util.List; 22 | 23 | /** 24 | * Interface for the Searching problem. 25 | * @param T - The type of the element to be searched 26 | */ 27 | public interface SearchingAlg { 28 | 29 | final int NIL = -1; 30 | 31 | /** 32 | * Returns the index of the first occurence of target in elements. 33 | * If elements doesn't contain target, NIL is returned; 34 | */ 35 | int indexOf(List elements, T target); 36 | } 37 | -------------------------------------------------------------------------------- /algorithms/The Selection Problem/README.md: -------------------------------------------------------------------------------- 1 | The Selection Problem 2 | ===================== 3 | 4 | ##Reference:## 5 | * CLRS 3rd Edition - Chapter 9 6 | -------------------------------------------------------------------------------- /algorithms/The Sorting Problem/README.md: -------------------------------------------------------------------------------- 1 | The Sorting Problem 2 | =================== 3 | 4 | ####Input#### 5 | Sequence of `N` numbers `A = [a1, a2, a3, ..., aN]` 6 | 7 | ####Output#### 8 | Permutation of the `N` elements in `A` such that `[a1 <= a2 <= a3 <= ... <= aN]` 9 | 10 | ####Example#### 11 | 1. `A=[9,8,7,6,5,4,3,2]` 12 | 2. `f(A)` 13 | 3. `A=[2,3,4,5,6,7,8,9]` 14 | 15 | ##Reference## 16 | * CLRS 3rd Edition - Section 2.1 17 | -------------------------------------------------------------------------------- /algorithms/The Sorting Problem/java/InsertionSort.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013, 2014 Jeanderson Barros Candido 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | * 18 | * Contributors: 19 | * Jeanderson Candido - Initial Implementation 20 | */ 21 | import java.util.List; 22 | import java.lang.Comparable; 23 | /** 24 | * The Insertion Sort uses an incremental approach. 25 | * 26 | * Characteristics: 27 | * Running-time: Quadratic - BigOh(n^2) 28 | * This algorithm is input-sensitive. If the input is already sorted (best case), 29 | * it runs in linear time. This algorithm is useful and efficient for tiny arrays 30 | * and arrays "pre-sorted". The worst case is having an inverted array yielding 31 | * quadratic time. 32 | * 33 | * Loop invariant: 34 | * The index i iterates over all elements, starting from the second value such 35 | * that the subarray in the range [0, i-1] is alway sorted. 36 | * 37 | * Reference 38 | * CLRS 3rd Edition - Section 2.1 39 | */ 40 | public class InsertionSort> implements SortingAlg { 41 | 42 | @Override 43 | public void sort(List elements) { 44 | if (elements == null) return; 45 | 46 | for (int i = 1; i < elements.size(); i++) { 47 | T key = elements.get(i); 48 | int j = i - 1; 49 | while (j >= 0 && isLessThan(key, elements.get(j))) { 50 | elements.set(j + 1, elements.get(j)); 51 | j--; 52 | } 53 | elements.set(j + 1, key); 54 | } 55 | } 56 | 57 | /* Returns true if the first is less than the second. 58 | * (an easier way to read the compareTo method) 59 | */ 60 | private boolean isLessThan(T first, T second) { 61 | return (first.compareTo(second) < 0); 62 | } 63 | 64 | public static void main(String[] args) { 65 | SortingAlg alg = new InsertionSort(); 66 | List elems = java.util.Arrays.asList(9,5,2,7,3,8,2,1,4,7,5,3,9); 67 | alg.sort(elems); 68 | for (int i = 0; i < elems.size() - 1; i++) { 69 | if (elems.get(i).compareTo(elems.get(i+1)) > 0) 70 | throw new java.lang.RuntimeException("Elems should be sorted."); 71 | } 72 | System.out.println("All tests passed."); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /algorithms/The Sorting Problem/java/MergeSort.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013, 2014 Jeanderson Barros Candido 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | * 18 | * Contributors: 19 | * Jeanderson Candido - Initial Implementation 20 | */ 21 | import java.lang.Comparable; 22 | import java.util.List; 23 | import java.util.ArrayList; 24 | /** 25 | * The Merge-Sort algorithm uses a Divide And Conquer approach. 26 | * 27 | * Characteristics: 28 | * Running time: Linear-Logarithmic BigOh(N * log(N)) 29 | * This algorithm requires extra memory to solve the sorting problem. Although 30 | * It is faster than Insertion Sort for large sequences, the overhead of the 31 | * Merge Sort for small sequences is much more than required by the Insertion 32 | * Sort. A good optimization would be using Insertion Sort when the size of the 33 | * sequence is small enough. 34 | * 35 | * Recurrence Function: 36 | * T(n) = 2 * T(n / 2) + f(n) 37 | * 38 | * Reference: 39 | * CLRS 3rd Edition - Section 2.3.1 40 | */ 41 | public class MergeSort> implements SortingAlg { 42 | 43 | private List buffer; 44 | 45 | // wrapper function 46 | @Override 47 | public void sort(List elements) { 48 | if (elements == null) 49 | return; 50 | 51 | // Give enough space to avoid having to keep resizing. 52 | // Remember that by doing this, buffer.size() == 0 53 | this.buffer = new ArrayList(elements.size()); 54 | 55 | sort(elements, 0, elements.size() - 1); 56 | this.buffer = null; 57 | } 58 | private void sort(List elements, int min, int max) { 59 | if (min == max) 60 | return; 61 | 62 | int mid = (min + max) >> 1; 63 | sort(elements, min, mid); 64 | sort(elements, mid + 1, max); 65 | 66 | merge(elements, min, mid, max); 67 | } 68 | private void merge(List elements, int min, int mid, int max) { 69 | if (lessThanOrEquals(elements.get(mid), elements.get(mid+1))) 70 | return; 71 | 72 | for (int k = min; k <= max; k++) 73 | this.buffer.add(k, elements.get(k)); 74 | 75 | int left = min; 76 | int right = mid + 1; 77 | for (int k = min; k <= max; k++) { 78 | if (left > mid) 79 | elements.set(k, this.buffer.get(right++)); 80 | else if (right > max) 81 | elements.set(k, this.buffer.get(left++)); 82 | else if (lessThan(this.buffer.get(left), this.buffer.get(right))) 83 | elements.set(k, this.buffer.get(left++)); 84 | else 85 | elements.set(k, this.buffer.get(right++)); 86 | } 87 | } 88 | // Helper functions 89 | private boolean lessThanOrEquals(T first, T second) { 90 | return (first.compareTo(second) <= 0); 91 | } 92 | private boolean lessThan(T first, T second) { 93 | return (first.compareTo(second) < 0); 94 | } 95 | // Simple driver 96 | public static void main(String[] args) { 97 | SortingAlg alg = new MergeSort(); 98 | List elems = java.util.Arrays.asList(9,5,2,7,3,8,2,1,4,7,5,3,9); 99 | alg.sort(elems); 100 | for (int i = 0; i < elems.size() - 1; i++) { 101 | if (elems.get(i).compareTo(elems.get(i+1)) > 0) 102 | throw new java.lang.RuntimeException("Elems should be sorted."); 103 | } 104 | System.out.println("All tests passed."); 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /algorithms/The Sorting Problem/java/QuickSortClassic.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013, 2014 Jeanderson Barros Candido 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | * 18 | * Contributors: 19 | * Jeanderson Candido - Initial Implementation 20 | */ 21 | import java.lang.Comparable; 22 | import java.util.List; 23 | 24 | public class QuickSortClassic> implements SortingAlg { 25 | 26 | @Override 27 | public void sort(List elements) { 28 | if (elements == null) 29 | return; 30 | sort(elements, 0, elements.size() - 1); 31 | } 32 | private void sort(List elements, int left, int right) { 33 | if (left < right) { 34 | int p = partition(elements, left, right); 35 | sort(elements, left, p-1); 36 | sort(elements, p+1, right); 37 | } 38 | } 39 | private int partition(List elements, int left, int right) { 40 | T pivot = elements.get(right); 41 | int i = left - 1; 42 | for (int j = left; j < right; j++) { 43 | if (isLessThan(elements.get(j), pivot)) { 44 | T greater = elements.get(++i); 45 | elements.set(i, elements.get(j)); 46 | elements.set(j, greater); 47 | } 48 | } 49 | T temp = elements.get(i + 1); 50 | elements.set(i + 1, pivot); 51 | elements.set(right, temp); 52 | 53 | return i + 1; 54 | } 55 | private boolean isLessThan(T first, T second) { 56 | return (first.compareTo(second) < 0); 57 | } 58 | 59 | // Simple driver 60 | public static void main(String[] args) { 61 | SortingAlg alg = new ClassicQuickSort(); 62 | List elems = java.util.Arrays.asList(9,5,2,7,3,8,2,1,4,7,5,3,9); 63 | alg.sort(elems); 64 | for (int i = 0; i < elems.size() - 1; i++) { 65 | if (elems.get(i).compareTo(elems.get(i+1)) > 0) { 66 | throw new java.lang.RuntimeException("Elems should be sorted."); 67 | } 68 | } 69 | System.out.println("All tests passed."); 70 | } 71 | } 72 | 73 | -------------------------------------------------------------------------------- /algorithms/The Sorting Problem/java/QuickSortMedian.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013, 2014 Jeanderson Barros Candido 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | * 18 | * Contributors: 19 | * Jeanderson Candido - Initial Implementation 20 | */ 21 | import java.lang.Comparable; 22 | import java.util.List; 23 | 24 | /** 25 | * The QuickSort algorithm uses a Divide and Conquer approach. 26 | * 27 | * This variation of the quick sort algorithm uses a median of three to choose 28 | * the pivot: We select the first, the middle, and the last element. Then, we 29 | * select the median element. This variation reduces the number of comparisons 30 | * and improves performance. 31 | */ 32 | public class QuickSortMedian> implements SortingAlg { 33 | 34 | @Override 35 | public void sort(List elements) { 36 | if (elements == null) 37 | return; 38 | sort(elements, 0, elements.size() - 1); 39 | } 40 | private void sort(List elements, int left, int right) { 41 | if (left < right) { 42 | int p = partition(elements, left, right); 43 | sort(elements, left, p-1); 44 | sort(elements, p+1, right); 45 | } 46 | } 47 | private int partition(List elements, int left, int right) { 48 | int pivotIndex = getMedianIndex(elements, left, right); 49 | T pivot = elements.get(pivotIndex); 50 | 51 | T temp = elements.get(right); 52 | elements.set(right, pivot); 53 | elements.set(pivotIndex, temp); 54 | 55 | int i = left - 1; 56 | for (int j = left; j < right; j++) { 57 | if (isLessThan(elements.get(j), pivot)) { 58 | T greater = elements.get(++i); 59 | elements.set(i, elements.get(j)); 60 | elements.set(j, greater); 61 | } 62 | } 63 | temp = elements.get(i + 1); 64 | elements.set(i + 1, pivot); 65 | elements.set(right, temp); 66 | 67 | return i + 1; 68 | } 69 | private boolean isLessThan(T first, T second) { 70 | return (first.compareTo(second) < 0); 71 | } 72 | private int getMedianIndex(List elements, int left, int right) { 73 | T first = elements.get(left); 74 | T middle = elements.get((left + right) >> 1); 75 | T last = elements.get(right); 76 | if ((isLessThan(middle, first) && isLessThan(first, last)) 77 | || (isLessThan(first, middle) && isLessThan(last, first))) 78 | return left; 79 | if ((isLessThan(last, first) && isLessThan(middle, last)) 80 | || (isLessThan(first, last) && isLessThan(last, middle))) 81 | return right; 82 | 83 | return (left + right) >> 1; 84 | } 85 | // Simple driver 86 | public static void main(String[] args) { 87 | SortingAlg alg = new MedianQuickSort(); 88 | List elems = java.util.Arrays.asList(9,5,2,7,3,8,2,1,4,7,5,3,9); 89 | alg.sort(elems); 90 | for (int i = 0; i < elems.size() - 1; i++) { 91 | if (elems.get(i).compareTo(elems.get(i+1)) > 0) { 92 | throw new java.lang.RuntimeException("Elems should be sorted."); 93 | } 94 | } 95 | System.out.println("All tests passed."); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /algorithms/The Sorting Problem/java/QuickSortRandomized.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013, 2014 Jeanderson Barros Candido 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | * 18 | * Contributors: 19 | * Jeanderson Candido - Initial Implementation 20 | */ 21 | import java.lang.Comparable; 22 | import java.util.List; 23 | import java.util.Random; 24 | 25 | public class QuickSortRandomized> implements SortingAlg { 26 | 27 | private static Random rand = new Random(); 28 | 29 | @Override 30 | public void sort(List elements) { 31 | if (elements == null) 32 | return; 33 | sort(elements, 0, elements.size() - 1); 34 | } 35 | private void sort(List elements, int left, int right) { 36 | if (left < right) { 37 | int p = partition(elements, left, right); 38 | sort(elements, left, p-1); 39 | sort(elements, p+1, right); 40 | } 41 | } 42 | // Similar to the Classic partitioning algorithm. 43 | // Randomly chooses the pivot and swap it with the rightmost element. 44 | private int partition(List elements, int left, int right) { 45 | int pivotIndex = rand.nextInt(right + 1 - left) + left; 46 | T pivot = elements.get(pivotIndex); 47 | 48 | T temp = elements.get(right); 49 | elements.set(right, pivot); 50 | elements.set(pivotIndex, temp); 51 | 52 | int i = left - 1; 53 | for (int j = left; j < right; j++) { 54 | if (isLessThan(elements.get(j), pivot)) { 55 | T greater = elements.get(++i); 56 | elements.set(i, elements.get(j)); 57 | elements.set(j, greater); 58 | } 59 | } 60 | temp = elements.get(i + 1); 61 | elements.set(i + 1, pivot); 62 | elements.set(right, temp); 63 | 64 | return i + 1; 65 | } 66 | private boolean isLessThan(T first, T second) { 67 | return (first.compareTo(second) < 0); 68 | } 69 | 70 | // Simple driver 71 | public static void main(String[] args) { 72 | SortingAlg alg = new QuickSortRandomized(); 73 | List elems = java.util.Arrays.asList(9,5,2,7,3,8,2,1,4,7,5,3,9); 74 | alg.sort(elems); 75 | for (int i = 0; i < elems.size() - 1; i++) { 76 | if (elems.get(i).compareTo(elems.get(i+1)) > 0) { 77 | throw new java.lang.RuntimeException("Elems should be sorted."); 78 | } 79 | } 80 | System.out.println("All tests passed."); 81 | } 82 | } 83 | 84 | 85 | -------------------------------------------------------------------------------- /algorithms/The Sorting Problem/java/QuickSortRandomizedMedian.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013, 2014 Jeanderson Barros Candido 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | * 18 | * Contributors: 19 | * Jeanderson Candido - Initial Implementation 20 | */ 21 | import java.lang.Comparable; 22 | import java.util.List; 23 | import java.util.Random; 24 | 25 | /** 26 | * The QuickSort algorithm uses a Divide and Conquer approach. 27 | * 28 | * This variation of the quick sort algorithm uses a median of three to choose 29 | * the pivot: We select the first, the middle, and the last element. Then, we 30 | * select the median element. This variation reduces the number of comparisons 31 | * and improves performance. 32 | * 33 | * Also, it randomly chooses three elements to find the median. 34 | */ 35 | public class QuickSortRandomizedMedian> implements SortingAlg { 36 | 37 | private static Random rand = new Random(); 38 | @Override 39 | public void sort(List elements) { 40 | if (elements == null) 41 | return; 42 | sort(elements, 0, elements.size() - 1); 43 | } 44 | private void sort(List elements, int left, int right) { 45 | if (left < right) { 46 | int p = partition(elements, left, right); 47 | sort(elements, left, p-1); 48 | sort(elements, p+1, right); 49 | } 50 | } 51 | private int partition(List elements, int left, int right) { 52 | int pivotIndex = getMedianIndex(elements, left, right); 53 | T pivot = elements.get(pivotIndex); 54 | 55 | T temp = elements.get(right); 56 | elements.set(right, pivot); 57 | elements.set(pivotIndex, temp); 58 | 59 | int i = left - 1; 60 | for (int j = left; j < right; j++) { 61 | if (isLessThan(elements.get(j), pivot)) { 62 | T greater = elements.get(++i); 63 | elements.set(i, elements.get(j)); 64 | elements.set(j, greater); 65 | } 66 | } 67 | temp = elements.get(i + 1); 68 | elements.set(i + 1, pivot); 69 | elements.set(right, temp); 70 | 71 | return i + 1; 72 | } 73 | private boolean isLessThan(T first, T second) { 74 | return (first.compareTo(second) < 0); 75 | } 76 | private int getMedianIndex(List elements, int left, int right) { 77 | int[] indexes = new int[3]; 78 | for (int i = 0; i < indexes.length; i++) { 79 | indexes[i] = rand.nextInt(right - left + 1) + left; 80 | } 81 | T first = elements.get(indexes[0]); 82 | T middle = elements.get(indexes[1]); 83 | T last = elements.get(indexes[2]); 84 | if ((isLessThan(middle, first) && isLessThan(first, last)) 85 | || (isLessThan(first, middle) && isLessThan(last, first))) 86 | return indexes[0]; 87 | if ((isLessThan(last, first) && isLessThan(middle, last)) 88 | || (isLessThan(first, last) && isLessThan(last, middle))) 89 | return indexes[2]; 90 | 91 | return indexes[1]; 92 | } 93 | // Simple driver 94 | public static void main(String[] args) { 95 | SortingAlg alg = new QuickSortRandomizedMedian(); 96 | List elems = java.util.Arrays.asList(9,5,2,7,3,8,2,1,4,7,5,3,9); 97 | alg.sort(elems); 98 | for (int i = 0; i < elems.size() - 1; i++) { 99 | if (elems.get(i).compareTo(elems.get(i+1)) > 0) { 100 | throw new java.lang.RuntimeException("Elems should be sorted."); 101 | } 102 | } 103 | System.out.println("All tests passed."); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /algorithms/The Sorting Problem/java/SelectionSort.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013, 2014 Jeanderson Barros Candido 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | * 18 | * Contributors: 19 | * Jeanderson Candido - Initial Implementation 20 | */ 21 | import java.util.List; 22 | import java.lang.Comparable; 23 | /** 24 | * The Selection Sort algorithm uses an incremental approach. 25 | * 26 | * Characteristics: 27 | * Running time: Quadratic - BigOh(n^2) 28 | * Regardless of the input, it will always be quadratic. However, the Selection 29 | * Sort algorithm perform less memory swaps than Insertion Sort. 30 | * 31 | * Loop Invariant: 32 | * The inner loop will find the index (min) of the minimum i-th value. Therefore, 33 | * by the end of each loop, the range [0...i-1] is sorted 34 | * 35 | * Reference: 36 | * CLRS 3rd Edition - Problem 2.2-2 37 | */ 38 | public class SelectionSort> implements SortingAlg { 39 | 40 | @Override 41 | public void sort(List elements) { 42 | if (elements == null) return; 43 | for (int i = 0; i < elements.size() - 1; i++) { 44 | int min = i; 45 | for (int j = i + 1; j < elements.size(); j++) { 46 | if (isLessThan(elements.get(j), elements.get(min))) 47 | min = j; 48 | } 49 | T temp = elements.get(i); 50 | elements.set(i, elements.get(min)); 51 | elements.set(min, temp); 52 | } 53 | } 54 | private boolean isLessThan(T first, T second) { 55 | return first.compareTo(second) < 0; 56 | } 57 | public static void main(String[] args) { 58 | SortingAlg alg = new SelectionSort(); 59 | List elems = java.util.Arrays.asList(9,5,2,7,3,8,2,1,4,7,5,3,9); 60 | alg.sort(elems); 61 | for (int i = 0; i < elems.size() - 1; i++) { 62 | if (elems.get(i).compareTo(elems.get(i+1)) > 0) 63 | throw new java.lang.RuntimeException("Elems should be sorted."); 64 | } 65 | System.out.println("All tests passed."); 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /algorithms/The Sorting Problem/java/SortingAlg.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013, 2014 Jeanderson Barros Candido 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | * 18 | * Contributors: 19 | * Jeanderson Candido - Initial Implementation 20 | */ 21 | import java.lang.Comparable; 22 | import java.util.List; 23 | /** 24 | * Interface for the Sorting problem. It is convenient to use the Comparable interface. 25 | * @param T - Type of the objects to be sorted 26 | */ 27 | public interface SortingAlg> { 28 | /** 29 | * Reorders the given sequence of elements in ascending sorted order. 30 | */ 31 | void sort(List elements); 32 | } 33 | -------------------------------------------------------------------------------- /out-of-date/PROBLEMS.md: -------------------------------------------------------------------------------- 1 | Problems 2 | -------- 3 | 4 | ## The Range Minimum/Maximum Query (RMQ) problem 5 | 6 | Given a range [i, j] and M queries, return the maximum (or minimum) element within the given range. 7 | Segment Tree is a useful data structure to solve this problem efficiently. It allows to perform 8 | queries in O(log(n)) time. Therefore, for M queries, the solution is O(M * log(n)). 9 | -------------------------------------------------------------------------------- /out-of-date/cpp/datastructures/priority_queue.cpp: -------------------------------------------------------------------------------- 1 | /* PRIORITY QUEUE 2 | * 3 | * Flavors: 4 | * MAX-PRIORITY Queue 5 | * MIN-PRIORITY Queue 6 | * 7 | * Application: 8 | * Elements are retrieved by priority instead of the typical QUEUE policy 9 | * "first-in first-out" (FIFO). There are many applications in CS. 10 | * 11 | * Implementation: 12 | * In order to achieve an efficient PRIORITY QUEUE, consider a {min/max}HEAP 13 | */ 14 | const int ROOT = 1; 15 | const int NIL = -1; 16 | int lenght, heap_sz; 17 | 18 | inline int parent(int i) { return (i >> 1); } 19 | inline int right(int i) { return (i << 1); } 20 | inline int left(int i) { return (i << 1) + 1; } 21 | 22 | void heapfy(int *A, int i) { 23 | int rgt = right(i); 24 | int lft = left(i); 25 | int largest = i; 26 | if (rgt <= heap_sz && A[rgt] < A[largest]) largest=rgt; 27 | if (lft <= heap_sz && A[lft] < A[largest]) largest=lft; 28 | if (largest != i) { 29 | int tmp = A[i]; 30 | A[i] = A[largest]; 31 | A[largest] = tmp; 32 | heapfy(A, largest); 33 | } 34 | } 35 | 36 | void build(int *A, int n) { 37 | lenght = heap_sz = n; 38 | A[0] = NIL; 39 | n >>= 1; 40 | while(n >= ROOT) { 41 | heapfy(A, n); 42 | n--; 43 | } 44 | } 45 | 46 | /* PRIORITY QUEUE interface 47 | * 48 | * ..............INSERT(A, x): Inserts element X in the queue A 49 | * CHANGE_KEY(A, i, priority): Changes i-th priority to a new priority 50 | * ................EXTRACT(A): Extracts the highest priority element 51 | * ...........MAX_PRIORITY(A): Returns the max priority element 52 | */ 53 | bool insert(int *A, int x) { 54 | if (heap_sz == lenght) return false; 55 | A[++heap_sz] = x; 56 | int i = heap_sz; 57 | while (i > ROOT && A[i] > A[parent(i)]) { 58 | int tmp = A[parent(i)]; 59 | A[parent(i)] = A[i]; 60 | A[i--] = tmp; 61 | } 62 | return true; 63 | } 64 | 65 | int extract(int *A) { 66 | if (heap_sz <= 0) return NIL; 67 | int extracted = A[ROOT]; 68 | A[ROOT] = A[heap_sz--]; 69 | heapfy(A, ROOT); 70 | 71 | return extracted; 72 | } 73 | 74 | inline int max_priority(int *A) { 75 | return ((heap_sz <= 0) ? NIL : A[ROOT]); 76 | } 77 | 78 | // TODO 79 | void change_key(int *A, int i, int priority) { 80 | 81 | } 82 | 83 | // TODO Driver 84 | int main() { return 0; } 85 | -------------------------------------------------------------------------------- /out-of-date/cpp/samples/rmq_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | // Assume INF as the Max value in A plus one. 6 | #define INF 100 7 | #define MAXN 100 8 | 9 | int A[MAXN], T[MAXN << 2]; 10 | inline int left(int n) { return 2*n + 1; } 11 | inline int right(int n) { return 2*(n + 1); } 12 | 13 | void build(int n, int i, int j) { 14 | if (i == j) { 15 | T[n] = A[i]; 16 | 17 | } else { 18 | int mid = (i+j) / 2; 19 | build(left(n), i, mid); 20 | build(right(n), mid+1, j); 21 | T[n] = min(T[left(n)], T[right(n)]); 22 | } 23 | } 24 | 25 | int query(int n, int i, int j, int a, int b) { 26 | if (j < a || i > b) return INF; 27 | if (a == b) return A[a]; 28 | if (i >= a && j <= b) return T[n]; 29 | int mid = (i + j)/2; 30 | int p1 = query(left(n), i, mid, a, b); 31 | int p2 = query(right(n), mid+1, j, a, b); 32 | return min(p1, p2); 33 | } 34 | void update(int x, int i, int N) { 35 | A[i] = x; 36 | build(0, 0, N-1); 37 | } 38 | 39 | int main() { 40 | // Dummy data 41 | int N = 10; 42 | for (int i=0; i < N; i++) { 43 | A[i] = i; 44 | } 45 | build(0, 0, N-1); 46 | 47 | int TC, a, b; 48 | scanf("%d", &TC); 49 | char op; 50 | while(TC--) { 51 | scanf(" %c", &op); 52 | if (op == 'u') { 53 | scanf("%d %d", &a, &b); 54 | update(a, b, N); 55 | } else if (op == 'q') { 56 | scanf("%d %d", &a, &b); 57 | printf("%d\n", query(0, 0, N-1, a, b)); 58 | } else { 59 | printf("Unknown option\n"); 60 | } 61 | } 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /out-of-date/cpp/searching/rmq.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Range Minimum Query (RMQ) 3 | * 4 | * In this set of problems, we have a SEQUENCE OF VALUES and we want to know 5 | * what is the MINIMUM element given the lower and upper indexes: 6 | * 7 | * PARAMETERS: 8 | * vector of values 9 | * lower and upper indexes (range) 10 | * 11 | * OUTPUT: 12 | * MINIMUM VALUE of the given range (other versions may consider the index of the minimum value) 13 | */ 14 | 15 | /** 16 | * Naive approach: O(n) 17 | * 18 | * Let's assume minimum as the i-th value. Then, we perform a linear search through the j-th element 19 | * checking if it's lower than the current minimum element. 20 | */ 21 | int rmq(int *values, int i, int j) { 22 | int lower = values[i]; 23 | for (int k = i + 1; k <= j; k++) { 24 | if (values[k] < lower) 25 | lower = values[k]; 26 | } 27 | return lower; 28 | } 29 | 30 | /** 31 | * What's the problem? Imagine that we will be performing M queries. If a single query takes 32 | * O(n) then we will have the asymptotic complexity of O(Mn) to solve our problem... 33 | * 34 | * ...CAN WE DO BETTER?! 35 | * 36 | * Intuitively, we could think about optimizing our linear search to a logarithmic complexity 37 | * to have O(Mlog(n)) but HOW? 38 | * 39 | * What if we had a preprocessed tree to store the minimum element of two children? Then our 40 | * query would be proportional to the height of this tree (log(n)). It seems to be a promising 41 | * approach. Let's go deep further on this: 42 | * 43 | * Assuming the following values: 44 | * A = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} 45 | * 46 | * Building the auxiliary tree, we would have: 47 | * 48 | * T = {min(A[0..N-1]), min(A[0..(N-1)/2]), min(A[(N-1)/2..N]), ... min(A[0]), .. min(A[N-1])} 49 | * 50 | * Have you seen this structure before? Seems like we could use a heap-like structure for our 51 | * auxiliary heap, right? Now, remember that for N leaves, we will require N*2 to represent each node in 52 | * an array. Asymptoticly speaking, we are "sacrificing" memory to speed up our lookup. As mentioned 53 | * before, 2 * N is all we need ( O(n) extra memory). 54 | */ 55 | 56 | /* 57 | * Because we are using a heap-like structure, we need to define the left and right children for the i-th 58 | * node. The following methods return indexes corresponding to an element. 59 | * For the sake of simplicity, let's assume 0 as the root our auxiliary tree. Also, A is the vector of 60 | * values and T is the pre-processed tree. Finally, we have the following: 61 | */ 62 | inline int right(int i) { 63 | return (i + 1) << 1; 64 | } 65 | inline int left(int i) { 66 | return (i << 1) + 1; 67 | } 68 | 69 | /* 70 | * Now, we need a sub-routine to build our auxiliary tree. Inspired by the Divide and Conquer approach 71 | * we come up with the following build routine O(log(n)): 72 | */ 73 | void build(int n, int i, int j) { 74 | if (i == j) T[n] = A[i]; 75 | else { 76 | int mid = (i + j)/2; 77 | build(left(n), i, mid); 78 | build(right(n), mid+1, j); 79 | T[n] = min(T[left(n)], T[right(n)]); 80 | } 81 | } 82 | 83 | /* 84 | * Nice! We know how to build our pre-processed tree to speed up our lookup procedure but how are we going 85 | * to use it for queries? 86 | */ 87 | int query(int n, int i, int j, int a, int b) { 88 | if (j < a || i > b) return INF; 89 | if (a == b) return A[a]; 90 | if (i >= a && j <= b) return T[n]; 91 | 92 | int mid = (i + j) / 2; 93 | int q1 = query(left(n), i, mid, a, b); 94 | int q2 = query(right(n), mid+1, j, a, b); 95 | 96 | return min(q1, q2); 97 | } 98 | -------------------------------------------------------------------------------- /out-of-date/cpp/sorting/heap_sort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /* The HEAP data structure: 4 | * - From the first to the 2nd last level, it's a COMPLETE TREE (node has 0 5 | * or 2 children). Elements are inserted FROM LEFT->RIGHT in the last level 6 | * 7 | * - Heap property: A[parent(i)] <= A[i] (min-heap) 8 | * A[parent(i)] >= A[i] (max-heap) 9 | * 10 | * - Due to the heap property (above), extract min/max requires O(1) + cost 11 | * to maintain the heap property 12 | * 13 | * - Since the heap is a complete binary tree, its height is lg(n). The 14 | * implication of this is that any operation in a branch will be O(log(n)) 15 | * 16 | * Properties (using arrays): 17 | * - given a k-th element, any k > (heap_size / 2) is a LEAF 18 | * - For the sake of simplicity, ROOT = A[1] (A[0] = SENTINEL) 19 | * - A.length => Length of A (max capacity) 20 | * - A.heap_size => # of values in the heap (0 <= A.heap_size <= A.length) 21 | * - parent(i): A[i >> 1]; 22 | * - left(i): A[i << 1]; 23 | * - right(i): A[(i << 1) + 1]; 24 | */ 25 | int length; 26 | int heap_size; 27 | // int *values; since we are using local pointers, this is not necessary 28 | 29 | inline int parent(int i) { return (i >> 1); } 30 | inline int left(int i) { return (i << 1); } 31 | inline int right(int i) { return (i << 1) + 1; } 32 | 33 | /* HEAPFY (max-heap) 34 | * 35 | * Running time: O(log(n)) 36 | * 37 | * Responsible to maintain the HEAP PROPERTY. 38 | * Assumes the children of i obeys the heap property but it's not guaranteed 39 | * that i is in the right place. 40 | * 41 | * "floats" down the improper element. As we saw previously, it's an operation 42 | * from a node to the root. Worst case is that the node floats from the root to 43 | * the leaf, therefore height = log(n). 44 | */ 45 | void heapfy(int *a, int i) { 46 | int lft = left(i); 47 | int rght = right(i); 48 | int largest = i; 49 | if (lft <= heap_size && a[i] < a[lft]) 50 | largest = lft; 51 | if (rght <= heap_size && a[largest] < a[rght]) 52 | largest = rght; 53 | if (largest != i) { 54 | int tmp = a[i]; 55 | a[i] = a[largest]; 56 | a[largest] = tmp; // A[largest] has the old A[i] value! 57 | heapfy(a, largest); // Needs to check if i is in the proper place 58 | } 59 | } 60 | 61 | /* BUILD HEAP 62 | * 63 | * Running time: O(n). Because it iterates over n/2 nodes and calls HEAPFY for 64 | * each of them, we are attempted to say that it's an O(n * log(n)) algorithm. 65 | * However, mathematical proof shows that this bound can be tighter to O(n). 66 | * It's jut a matter of summations and getting a better bound. 67 | * 68 | * The underlying idea is to call HEAPFY for all internal nodes. 69 | */ 70 | void build(int *a, int n) { 71 | heap_size = length = n; 72 | a[0] = -1; // sentinel 73 | n >>= 1; // only iterate over non-leaves until reach the root 74 | while(n >= 1) { 75 | heapfy(a, n); 76 | n--; 77 | } 78 | } 79 | 80 | /* Heap Sort 81 | * 82 | * Like INSERTION SORT, it's a in-place sorting algorithm 83 | * Like MERGE SORT, it's a linear-logarithmic sorting O(n * log(n)) 84 | * 85 | * Unlike the mentioned algorithms, HEAP SORT uses a DATA STRUCTURE to manage 86 | * information (the HEAP). 87 | * 88 | * The underlying idea of HEAP SORT is organizing a list of keys in a MAX-HEAP, 89 | * then we exchange the ROOT with A[heap_size]. After that is just a matter of 90 | * excluding the last element and calling HEAPFY to the root. 91 | */ 92 | void heapsort(int *a, int n) { 93 | build(a, n); 94 | int i = 1; 95 | while (i <= heap_size) { 96 | int tmp = a[heap_size]; 97 | a[heap_size] = a[i]; 98 | a[i] = tmp; 99 | 100 | // this HAVE to be decreased before calling HEAPFY and AFTER swapping 101 | // the values. What would happen if we decrease after calling HEAPFY? 102 | heap_size--; 103 | 104 | heapfy(a, i); 105 | } 106 | } 107 | 108 | 109 | // Driver based on Figure 6.2, 6.3 from Cormen. Use as input the file test_heap.txt 110 | void print(int *values) { 111 | for (int i=1; i <= length; i++) printf("%d ", values[i]); 112 | printf("\n"); 113 | } 114 | 115 | int main() { 116 | int n; 117 | scanf("%d", &n); 118 | 119 | // heap initialization 120 | int *values = new int[n+1]; 121 | heap_size = 0; 122 | length = n; 123 | values[0] = -1; // sentinel 124 | 125 | // inserting elements 126 | for (int i=1; i <= n; i++) { scanf("%d", (values+i)); heap_size++; }; 127 | heapfy(values, 2); 128 | print(values); 129 | 130 | // Testing build heap 131 | scanf("%d", &n); 132 | int *a = new int[n+1]; 133 | for (int i=1; i <= n; i++) { scanf("%d", (a+i)); }; 134 | build(a, n); 135 | print(a); 136 | 137 | // Testing heapsort 138 | printf("Sorting the following heap: "); 139 | print(values); 140 | heapsort(values, n); 141 | print(values); 142 | 143 | printf("Sorting the following heap: "); 144 | print(a); 145 | heapsort(a, n); 146 | print(a); 147 | 148 | delete [] values; 149 | delete [] a; 150 | 151 | return 0; 152 | } 153 | -------------------------------------------------------------------------------- /out-of-date/cpp/sorting/test_heap.txt: -------------------------------------------------------------------------------- 1 | 10 2 | 16 4 10 14 7 9 3 2 8 1 3 | 10 4 | 4 1 3 2 16 9 10 14 8 7 5 | 6 | -------------------------------------------------------------------------------- /out-of-date/java/QuickFind.java: -------------------------------------------------------------------------------- 1 | import java.lang.IllegalArgumentException; 2 | import java.util.Arrays; 3 | 4 | public class QuickFind implements UnionFind { 5 | 6 | private int[] id; 7 | 8 | public QuickFind(int n) { 9 | if (n <= 0) 10 | throw new IllegalArgumentException("Value n should be greater than 0"); 11 | 12 | id = new int[n]; 13 | for (int i = 0; i < n; i++) { 14 | id[i] = i; 15 | } 16 | } 17 | 18 | @Override 19 | public void union(int p, int q) { 20 | if (!isConnected(p, q)) { 21 | int pid = id[p]; 22 | for (int i = 0; i < id.length; i++) { 23 | if (id[i] == pid) 24 | id[i] = id[q]; 25 | } 26 | } 27 | } 28 | 29 | @Override 30 | public boolean isConnected(int p, int q) { 31 | if (isValid(q) && isValid(p)) { 32 | return id[p] == id[q]; 33 | } 34 | return false; 35 | } 36 | 37 | @Override 38 | public String toString() { 39 | return Arrays.toString(this.id); 40 | } 41 | 42 | private boolean isValid(int p) { 43 | return (p >= 0 && p < id.length); 44 | } 45 | 46 | /** 47 | * Demo 48 | */ 49 | public static void main(String[] args) { 50 | int n = 10; 51 | 52 | UnionFind uf = new QuickFind(n); 53 | for (int i = 0; i < n; i++) { 54 | assertConnection(uf, i, i); 55 | } 56 | System.out.println(uf); 57 | 58 | int[] pairs = {5, 8, 2, 5, 9, 7, 6, 5, 3, 8, 2, 0}; 59 | for (int i = 1; i < pairs.length; i += 2) { 60 | uf.union(pairs[i-1], pairs[i]); 61 | assertConnection(uf, pairs[i-1], pairs[i]); 62 | System.out.println(uf); 63 | } 64 | } 65 | 66 | private static void assertConnection(UnionFind uf, int p, int q) { 67 | if (!uf.isConnected(p, q) && !uf.isConnected(q, p)) 68 | System.out.println("Fail, points should be connected"); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /out-of-date/java/UnionFind.java: -------------------------------------------------------------------------------- 1 | public interface UnionFind { 2 | 3 | void union(int p, int q); 4 | 5 | boolean isConnected(int p, int q); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /out-of-date/java/WeightedQuickUnion.java: -------------------------------------------------------------------------------- 1 | import java.lang.IllegalArgumentException; 2 | import java.util.Arrays; 3 | 4 | public class WeightedQuickUnion implements UnionFind { 5 | 6 | private int id[]; 7 | private int sz[]; 8 | 9 | public WeightedQuickUnion(int n) { 10 | if (n <= 0) 11 | throw new IllegalArgumentException("Value n should be greater than 0"); 12 | 13 | id = new int[n]; 14 | sz = new int[n]; 15 | for (int i = 0; i < n; i++) { 16 | id[i] = i; 17 | sz[i] = 1; 18 | } 19 | } 20 | 21 | @Override 22 | public void union(int p, int q) { 23 | if (!isConnected(p, q)) { 24 | if (sz[root(q)] < sz[root(p)]) { 25 | id[root(q)] = root(p); 26 | sz[root(p)] += sz[root(q)]; 27 | } else { 28 | id[root(p)] = root(q); 29 | sz[root(q)] += sz[root(p)]; 30 | } 31 | } 32 | } 33 | 34 | @Override 35 | public boolean isConnected(int p, int q) { 36 | if (isValid(p) && isValid(q)) { 37 | return root(p) == root(q); 38 | } 39 | return false; 40 | } 41 | 42 | @Override 43 | public String toString() { 44 | StringBuilder str = new StringBuilder(); 45 | str.append("Roots:\t").append(Arrays.toString(this.id)); 46 | str.append("\n").append("Size:\t"); 47 | str.append(Arrays.toString(this.sz)); 48 | return str.toString(); 49 | } 50 | 51 | private int root(int node) { 52 | while (id[node] != node) { 53 | node = id[node]; 54 | } 55 | return node; 56 | } 57 | 58 | private boolean isValid(int p) { 59 | return (p >= 0 && p < id.length); 60 | } 61 | 62 | /** 63 | * Demo 64 | */ 65 | public static void main(String[] args) { 66 | int n = 10; 67 | 68 | UnionFind uf = new WeightedQuickUnion(n); 69 | for (int i = 0; i < n; i++) { 70 | assertConnection(uf, i, i); 71 | } 72 | System.out.println(uf); 73 | 74 | int[] pairs = {8, 9, 5, 1, 6, 7, 7, 3, 5, 0, 8, 5, 2, 4, 7, 2, 2, 0}; 75 | for (int i = 1; i < pairs.length; i += 2) { 76 | uf.union(pairs[i-1], pairs[i]); 77 | assertConnection(uf, pairs[i-1], pairs[i]); 78 | System.out.println(uf); 79 | } 80 | } 81 | 82 | private static void assertConnection(UnionFind uf, int p, int q) { 83 | if (!uf.isConnected(p, q) && !uf.isConnected(q, p)) 84 | System.out.println("Fail, points should be connected"); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /training/CoinChangeProblem.java: -------------------------------------------------------------------------------- 1 | import java.util.Arrays; 2 | 3 | /* 4 | * Given an arbitrary amount of money and a set of coin denominations, 5 | * do you know how to compute the minimum number of coins necessary 6 | * to change the informed amount of money? 7 | * 8 | * For instance, given $25 and the coins $1, $5, and $10, you can change 9 | * $25 with at least 3 coins: 10+10+5 10 | */ 11 | class Main { 12 | 13 | /* This recursive approach solves the problem correctly 14 | * but it does not scale for large inputs. 15 | * 16 | * Can you guess why? :) 17 | */ 18 | static int solve(int value, int[] coins) { 19 | if (value == 0) return 0; 20 | int minCoins = -1; 21 | for (int coin : coins) { 22 | if (coin <= value) { 23 | int numCoins = solve(value - coin, coins); 24 | if (minCoins == -1 || minCoins > numCoins + 1) 25 | minCoins = numCoins + 1; 26 | } 27 | } 28 | return minCoins; 29 | } 30 | 31 | /* 32 | * Is this really faster? If so, can you tell why? 33 | */ 34 | static int faster(int value, int[] coins) { 35 | int[] minCoins = new int[value + 1]; 36 | minCoins[0] = 0; 37 | for (int currentValue = 1; currentValue <= value; currentValue++) { 38 | minCoins[currentValue] = -1; 39 | for (int coin : coins) { 40 | if (coin <= currentValue) { 41 | int numCoins = minCoins[currentValue - coin] + 1; 42 | if (minCoins[currentValue] == -1 43 | || minCoins[currentValue] > numCoins) { 44 | minCoins[currentValue] = numCoins; 45 | } 46 | } 47 | } 48 | } 49 | return minCoins[value]; 50 | } 51 | 52 | static void correctness(int testValue, int[] testCoins) { 53 | System.out.printf("Test Value: %d, Test Coins: %s\n", testValue, Arrays.toString(testCoins)); 54 | int sol1 = solve(testValue, testCoins); 55 | int sol2 = faster(testValue, testCoins); 56 | if (sol1 != sol2) { 57 | System.err.printf("Wrong Answer - Recursive: %d, DP: %d\n", sol1, sol2); 58 | } else { 59 | System.out.printf("Correct Answer: %d\n", sol2); 60 | } 61 | } 62 | 63 | static void efficiency(int minValue, int maxValue, int[] testCoins) { 64 | System.out.println("N\tNaive\tDP"); 65 | for (int testValue = minValue; testValue <= maxValue; testValue += 10) { 66 | long t1 = System.currentTimeMillis(); 67 | solve(testValue, testCoins); 68 | t1 = System.currentTimeMillis() - t1; 69 | 70 | long t2 = System.currentTimeMillis(); 71 | faster(testValue, testCoins); 72 | t2 = System.currentTimeMillis() - t2; 73 | 74 | System.out.printf("%d\t%d\t%d\n", testValue, t1, t2); 75 | } 76 | } 77 | 78 | // Some tests... 79 | public static void main(String[] args) { 80 | correctness(25, new int[]{5, 10, 15}); 81 | correctness(40, new int[]{5, 10, 25, 50}); 82 | correctness(40, new int[]{5, 10, 20, 25, 50}); 83 | correctness(7, new int[]{1, 3, 4, 5}); 84 | 85 | System.out.println("----------"); 86 | efficiency(100, 150, new int[]{5, 10, 20, 25, 50}); 87 | 88 | System.out.println("----------"); 89 | int sol = faster(10_000_000, new int[]{5, 10, 20, 25, 50}); 90 | System.out.printf("For N = 10^7, Coin Change = %d\n", sol); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /training/FibModulus.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class FibModulus { 4 | 5 | private static long getFibonacciHuge(long n, int m) { 6 | int[] fib = new int[10_000_000]; 7 | fib[0] = 0; 8 | fib[1] = 1; 9 | 10 | int size = 2; 11 | for (int i = 2; i < fib.length; i++) { 12 | fib[i] = (fib[i - 1] + fib[i - 2]) % m; 13 | size++; 14 | if (fib[i] == 1 && fib[i - 1] == 0) { 15 | size -= 2; 16 | break; 17 | } 18 | } 19 | return fib[(int)(n % size)] % m; 20 | } 21 | public static void main(String[] args) { 22 | Scanner scanner = new Scanner(System.in); 23 | long n = scanner.nextLong(); 24 | int m = scanner.nextInt(); 25 | System.out.println(getFibonacciHuge(n, m)); 26 | } 27 | } 28 | 29 | -------------------------------------------------------------------------------- /training/Fibonacci.java: -------------------------------------------------------------------------------- 1 | import java.util.Scanner; 2 | 3 | public class Fibonacci { 4 | 5 | static final int MAXN = 10_000; 6 | static int[] memo = new int[MAXN]; 7 | 8 | static int fibSlow(int n) { 9 | return (n <= 1) ? n : (fibSlow(n - 1) + fibSlow(n - 2)); 10 | } 11 | 12 | static int fib(int n) { 13 | return memo[n]; 14 | } 15 | 16 | public static void main(String[] args) { 17 | memo[0] = 0; 18 | memo[1] = 1; 19 | for (int i = 2; i < MAXN; i++) { 20 | memo[i] = memo[i - 1] + memo[i - 2]; 21 | } 22 | 23 | Scanner in = new Scanner(System.in); 24 | int tc = in.nextInt(); 25 | while (tc-- > 0) { 26 | int value = in.nextInt(); 27 | System.out.println(String.format("%d %d", fibSlow(value), fib(value))); 28 | } 29 | in.close(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /training/Fibonacci.txt: -------------------------------------------------------------------------------- 1 | 6 2 | 0 3 | 1 4 | 2 5 | 3 6 | 4 7 | 5 8 | -------------------------------------------------------------------------------- /training/GCD.java: -------------------------------------------------------------------------------- 1 | import java.util.Scanner; 2 | 3 | public class GCD { 4 | 5 | public static int gcd(int a, int b) { 6 | return (b == 0) ? a : gcd(b, a % b); 7 | } 8 | 9 | public static void main(String[] args) { 10 | Scanner in = new Scanner(System.in); 11 | int tc = in.nextInt(); 12 | while (tc-- > 0) { 13 | int a = in.nextInt(); 14 | int b = in.nextInt(); 15 | System.out.println(gcd(Math.max(a, b), Math.min(a, b))); 16 | } 17 | in.close(); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /training/GCD.txt: -------------------------------------------------------------------------------- 1 | 6 2 | 10 5 3 | 5 10 4 | 100 99 5 | 99 100 6 | 357 234 7 | 234 357 8 | -------------------------------------------------------------------------------- /training/LCM.java: -------------------------------------------------------------------------------- 1 | import java.util.Scanner; 2 | 3 | public class LCM { 4 | public static int gcd(int a, int b) { 5 | if (b == 0) 6 | return a; 7 | return gcd(b, a % b); 8 | } 9 | public static void main(String[] args) { 10 | Scanner sc = new Scanner(System.in); 11 | int a = sc.nextInt(); 12 | int b = sc.nextInt(); 13 | 14 | // Truth: lcm(a, b) * gcd(a, b) = a * b 15 | long lcm = ((long)a * b) / gcd(Math.max(a, b), Math.min(a, b)); 16 | 17 | System.out.println(lcm); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /training/MaxPairwiseProduct.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.io.*; 3 | 4 | public class MaxPairwiseProduct { 5 | static long getMaxPairwiseProduct(int[] numbers) { 6 | int maxi = -1; 7 | for (int i = 0; i < numbers.length; i++) { 8 | if (maxi == -1 || numbers[maxi] < numbers[i]) 9 | maxi = i; 10 | } 11 | int maxj = -1; 12 | for (int i = 0; i < numbers.length; i++) { 13 | if (i != maxi && (maxj == -1 || numbers[maxj] < numbers[i])) { 14 | maxj = i; 15 | } 16 | } 17 | return (long) numbers[maxi] * numbers[maxj]; 18 | } 19 | 20 | public static void main(String[] args) { 21 | FastScanner scanner = new FastScanner(System.in); 22 | int n = scanner.nextInt(); 23 | int[] numbers = new int[n]; 24 | for (int i = 0; i < n; i++) { 25 | numbers[i] = scanner.nextInt(); 26 | } 27 | System.out.println(getMaxPairwiseProduct(numbers)); 28 | } 29 | 30 | static class FastScanner { 31 | BufferedReader br; 32 | StringTokenizer st; 33 | 34 | FastScanner(InputStream stream) { 35 | try { 36 | br = new BufferedReader(new InputStreamReader(stream)); 37 | } catch (Exception e) { 38 | e.printStackTrace(); 39 | } 40 | } 41 | 42 | String next() { 43 | while (st == null || !st.hasMoreTokens()) { 44 | try { 45 | st = new StringTokenizer(br.readLine()); 46 | } catch (IOException e) { 47 | e.printStackTrace(); 48 | } 49 | } 50 | return st.nextToken(); 51 | } 52 | 53 | int nextInt() { 54 | return Integer.parseInt(next()); 55 | } 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /training/MaxPairwiseProduct.txt: -------------------------------------------------------------------------------- 1 | 2 2 | 100000 90000 3 | -------------------------------------------------------------------------------- /training/README.md: -------------------------------------------------------------------------------- 1 | * Create a `.java` for the solution and a `.txt` for the input. 2 | * Use the auxiliar script `judge.sh` to compile and run the program: `judge.sh `. 3 | * Create more test cases with the file name pattern `.*txt`. 4 | -------------------------------------------------------------------------------- /training/Sum.java: -------------------------------------------------------------------------------- 1 | import java.util.Scanner; 2 | 3 | public class Sum { 4 | public static void main(String[] args) { 5 | Scanner sc = new Scanner(System.in); 6 | System.out.println(sc.nextInt() + sc.nextInt()); 7 | sc.close(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /training/Sum.txt: -------------------------------------------------------------------------------- 1 | 3 3 2 | -------------------------------------------------------------------------------- /training/greedy/CoinChange.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class CoinChange { 4 | 5 | public static void main(String[] args) { 6 | Scanner sc = new Scanner(System.in); 7 | int value = sc.nextInt(); 8 | 9 | int cnt = 0, 10 | quantity = 0; 11 | 12 | // Naturally Greedy 13 | int[] coins = new int[] {10, 5, 1}; 14 | for (int i = 0; i < coins.length; i++) { 15 | quantity = value / coins[i]; 16 | value -= quantity * coins[i]; 17 | cnt += quantity; 18 | if (value == 0) { 19 | break; 20 | } 21 | } 22 | System.out.println(cnt); 23 | sc.close(); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /training/greedy/FractionalKnapsack.java: -------------------------------------------------------------------------------- 1 | import java.util.Queue; 2 | import java.util.PriorityQueue; 3 | import java.util.Scanner; 4 | import java.lang.Comparable; 5 | 6 | public class FractionalKnapsack { 7 | 8 | static class Item implements Comparable { 9 | int value, weight; 10 | public Item(int v, int w) { 11 | this.value = v; 12 | this.weight = w; 13 | } 14 | @Override 15 | public int compareTo(Item other) { 16 | return (int)((float)other.value / other.weight) - (int)((float)this.value / this.weight); 17 | } 18 | @Override 19 | public String toString() { 20 | return String.format("(%d, %d)", this.value, this.weight); 21 | } 22 | } 23 | public static void main(String[] args0) { 24 | Scanner sc = new Scanner(System.in); 25 | 26 | int numItems = sc.nextInt(); 27 | int remainingWeight = sc.nextInt(); 28 | 29 | Queue items = new PriorityQueue<>(); 30 | while (numItems-- > 0) { 31 | int v = sc.nextInt(); 32 | int w = sc.nextInt(); 33 | items.add(new Item(v, w)); 34 | } 35 | 36 | float maxProfit = 0f; 37 | while (!items.isEmpty()) { 38 | Item curr = items.remove(); 39 | if (curr.weight > remainingWeight) { 40 | float fract = (float) remainingWeight / curr.weight; 41 | maxProfit += fract * curr.value; 42 | break; 43 | } else { 44 | maxProfit += curr.value; 45 | remainingWeight -= curr.weight; 46 | } 47 | } 48 | System.out.println(String.format("%.4f", maxProfit)); 49 | sc.close(); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /training/judge.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | FILE_NAME=$1 3 | javac -encoding UTF-8 $FILE_NAME.java 4 | if [[ $? == "0" ]]; then 5 | for testcase in $(ls . | grep $FILE_NAME.*txt); do 6 | echo "Runnig test case with input file $testcase:" 7 | cat $testcase 8 | echo "Result:" 9 | java -Xmx1024m $FILE_NAME < $testcase 10 | done; 11 | rm *.class 12 | fi 13 | --------------------------------------------------------------------------------