This certificate is awarded to:
16 |[Recipient's Name]
17 |For outstanding performance and dedication in the field of...
18 |Date: July 23, 2023
19 |├── .vscode └── settings.json ├── Certificate ├── index.html ├── script.js └── style.css ├── LICENSE ├── README.md ├── images ├── Algo.png ├── arrow.png ├── code.png ├── cross.png ├── dgm-1.png ├── dgm-2.png ├── dgm-3.png ├── dsa-logo.png └── menu.png ├── index.html ├── lesson-03 ├── index.html ├── quiz.css ├── quiz.html ├── quiz.js ├── script.js └── style.css ├── lesson-04 ├── index.html ├── script.js └── style.css ├── lesson-2 ├── index.html ├── quiz.css ├── quiz.html ├── quiz.js ├── script.js └── style.css ├── script.js └── style.css /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "[python]": { 3 | "editor.defaultFormatter": "ms-python.autopep8" 4 | }, 5 | "python.formatting.provider": "none" 6 | } -------------------------------------------------------------------------------- /Certificate/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 |This certificate is awarded to:
16 |For outstanding performance and dedication in the field of...
18 |Date: July 23, 2023
19 |Signature
22 |164 | DSA (Data Structures and Algorithms) in Python is a fundamental course 165 | that introduces the principles and implementation of various data 166 | structures and algorithms using the Python programming language. 167 |
168 | 169 |170 | In this course, you will learn about essential data structures such as 171 | arrays, linked lists, stacks, queues, trees, graphs, and hash tables, 172 | and explore their strengths and weaknesses in different scenarios. You 173 | will understand how to manipulate and organize data efficiently, 174 | improving the performance of your programs. 175 |
176 | 177 |178 | Additionally, the course delves into algorithm analysis and design 179 | techniques, enabling you to create efficient solutions for a wide 180 | range of problems. You will explore algorithms like sorting, 181 | searching, graph traversal, and dynamic programming. By understanding 182 | the underlying concepts, you will be able to write clean and optimized 183 | code. 184 |
185 | 186 |187 | Throughout the course, you will gain hands-on experience by 188 | implementing data structures and algorithms in Python. The practical 189 | exercises and coding assignments will reinforce your understanding and 190 | help you develop problem-solving skills. 191 |
192 | 193 |194 | Whether you are a beginner or an experienced programmer, this DSA 195 | course in Python will equip you with the necessary tools and knowledge 196 | to tackle complex programming challenges, enhance your logical 197 | thinking, and become a more proficient developer. 198 |
199 |203 | Once upon a time, a skilled architect named Alice faced a challenge 204 | while designing a bakery's order management system. Reflecting on her 205 | past experience of choosing wooden blocks for a window in her home, 206 | she realized the importance of selecting the perfect data structure. 207 | Inspired by the flexibility and adaptability of wooden blocks, she 208 | opted for a priority queue to efficiently manage the bakery's orders. 209 | Her decision proved to be a game-changer, streamlining operations and 210 | delighting customers. Alice's ability to draw from past experiences 211 | and choose the right data structure showcased her problem-solving 212 | prowess. 213 |
214 |220 | As per the above image you will never use bricks to build a window, 221 | like that as a Software Engineer , you have to choose the perfect Data 222 | Structures to solve a problem. 223 |
224 |227 | Now look at this picture very carefully... 228 |
229 |235 | This is the solution for the problem... 236 |
237 |Data Structure | 249 |Python | 250 |Java | 251 |C++ | 252 | 253 | 254 |
---|---|---|---|
Array | 256 |Lists | 257 |
258 | Native Array
259 | 260 | ArrayList 261 | |
262 |
263 | Native Array
264 | 265 | std::vector 266 | |
267 |
Hash Table | 270 |Dictionary | 271 |
272 | HashMap 273 | LinkedHashMap 274 | |
275 | std::map | 276 |
Linked List | 279 |Not Available | 280 |LinkedList | 281 |std::list | 282 |
168 | Data structures refer to the fundamental ways of organizing and storing data in a computer's memory to 169 | facilitate efficient manipulation and retrieval of information. These structures provide a systematic 170 | arrangement of data elements, defining the relationships between them and the operations that can be 171 | performed on them. Common data structures include arrays, linked lists, stacks, queues, trees, graphs, 172 | and hash tables, each designed to suit specific data management and processing needs. Choosing the right 173 | data structure is crucial in optimizing algorithms and ensuring optimal performance in software 174 | development and problem-solving. 175 |
176 |We can divide Data Structures into two parts . Like We have : - Liner Data Structures & Non-Liner Data Structures
182 |Python has some by default specific Data Structures like :-
219 |234 | Python allows us to create and use various types of Data Structures and you can control all of 235 | them . 236 |
237 |241 | In Python, a list data structure is an ordered collection of elements that can hold items of 242 | different data types, such as integers, strings, or even other lists. Lists are mutable, meaning 243 | their elements can be modified, added, or removed after creation. They are represented using 244 | square brackets [ ] and can be indexed and sliced to access specific elements or subsets of the 245 | list. Python lists offer versatile functionality, making them widely used for data storage, 246 | iteration, and manipulation in various programming tasks. 247 |
248 |
251 |
252 | # Creating a list
253 | my_list = [1, 2, 3, 4, 5]
254 |
255 | # Accessing elements in the list
256 | print("Element at index 0:", my_list[0])
257 | # Output: Element at index 0: 1
258 | print("Element at index 2:", my_list[2])
259 | # Output: Element at index 2: 3
260 |
261 | # Modifying elements in the list
262 | my_list[3] = 10
263 | print("Modified list:", my_list)
264 | # Output: Modified list: [1, 2, 3, 10, 5]
265 |
266 | # Appending elements to the list
267 | my_list.append(6)
268 | print("List after appending 6:", my_list)
269 | # Output: List after appending 6: [1, 2, 3, 10, 5, 6]
270 |
271 | # Removing elements from the list
272 | my_list.remove(3)
273 | print("List after removing 3:", my_list)
274 | # Output: List after removing 3: [1, 2, 10, 5, 6]
275 |
276 | # Slicing the list
277 | sliced_list = my_list[1:4]
278 | print("Sliced list:", sliced_list)
279 | # Output: Sliced list: [2, 10, 5]
280 |
281 | # Length of the list
282 | length_of_list = len(my_list)
283 | print("Length of the list:", length_of_list)
284 | # Output: Length of the list: 5
285 |
286 |
287 |
288 |
289 |
290 | In this code, we create a list called my_list and 292 | perform various operations such as 293 | accessing elements using index, modifying elements, appending elements, removing elements, 294 | slicing the list, and finding the length of the list. Lists in Python are very versatile and can 295 | be used in a wide range of scenarios for data storage and manipulation.
296 |A nested or multi-dimensional list is a list that 299 | contains other lists as its elements, creating a structure similar to a matrix or an array of 300 | arrays. Each element in the main list can be another list, and these sub-lists can have 301 | different lengths. Here's an example of a 2D nested list in Python:
302 |
304 |
305 | # Creating a nested list (2D list)
306 | nested_list = [
307 | [1, 2, 3],
308 | [4, 5, 6],
309 | [7, 8, 9]
310 | ]
311 |
312 | # Accessing elements in the nested list
313 | print("Element at row 0, column 1:", nested_list[0][1])
314 | # Output: Element at row 0, column 1: 2
315 | print("Element at row 2, column 2:", nested_list[2][2])
316 | # Output: Element at row 2, column 2: 9
317 |
318 | # Modifying elements in the nested list
319 | nested_list[1][0] = 10
320 | print("Modified nested list:", nested_list)
321 | # Output: Modified nested list: [[1, 2, 3], [10, 5, 6], [7, 8, 9]]
322 |
323 | # Appending a new row to the nested list
324 | new_row = [11, 12, 13]
325 | nested_list.append(new_row)
326 | print("Nested list after appending a new row:", nested_list)
327 | # Output: Nested list after appending a new row:
328 | # [[1, 2, 3], [10, 5, 6], [7, 8, 9], [11, 12, 13]]
329 |
330 | # Slicing the nested list
331 | sliced_list = nested_list[1:3]
332 | print("Sliced nested list:", sliced_list)
333 | # Output: Sliced nested list: [[10, 5, 6], [7, 8, 9]]
334 |
335 |
336 |
337 |
338 |
339 | In this example, nested_list is a 2D list with three 341 | rows, and each row is a list itself. We can access elements using two indices, one for the row 342 | and another for the column. The code demonstrates accessing, modifying, appending rows, and 343 | slicing the nested list. Multi-dimensional lists are useful when dealing with data organized in 344 | a grid-like structure, such as matrices or tables.
345 |
349 |
350 | list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, "Bhed"]
351 | print(len(list))
352 |
353 | # Output : 15
354 |
355 |
356 |
357 | Using len() function we can easily find the 360 | length / size of any Lists .
361 |In Python, negative indexing is a concept that allows 364 | you to access elements from the end of a list using negative numbers as indices. Instead of 365 | counting from the beginning (0) like positive indexing, negative indexing starts counting from 366 | the end (-1) of the list. This means that the last element of the list can be accessed using 367 | index -1, the second-to-last element using index -2, and so on. 368 |
369 |Here's how negative indexing works with a list :- 370 |
371 |
373 |
374 | # Creating a list
375 | my_list = [10, 20, 30, 40, 50]
376 |
377 | # Accessing elements using positive indexing
378 | print("Element at index 0:", my_list[0])
379 | # Output: Element at index 0: 10
380 | print("Element at index 3:", my_list[3])
381 | # Output: Element at index 3: 40
382 |
383 | # Accessing elements using negative indexing
384 | print("Element at index -1:", my_list[-1])
385 | # Output: Element at index -1: 50
386 | print("Element at index -3:", my_list[-3])
387 | # Output: Element at index -3: 30
388 |
389 |
390 |
391 |
392 | Using negative indexing can be especially useful when 394 | you want to access elements near the end of the list, or when the length of the list is not 395 | known, but you still need to access the last few elements. Negative indexing provides a 396 | convenient and concise way to achieve this without explicitly calculating the positive index 397 | from the length of the list. 398 |
399 |So, negative indexing is a powerful feature in Python 400 | lists that allows you to access elements from the end of the list using negative numbers as 401 | indices, making it easier and more intuitive to work with lists, especially when dealing with 402 | elements near the end. 403 |
404 |In Python, a tuple is an immutable, ordered collection 408 | of elements enclosed in 409 | parentheses ( ) or created without 410 | any brackets. Unlike lists, tuples cannot be modified after 411 | creation, making them "immutable" data structures. Tuples can hold elements of different data 412 | types, just like lists, but once a tuple is created, its elements and their order cannot be 413 | changed. 414 |
415 |Tuples in Python are fixed-size, ordered collections of 418 | elements, and are defined by enclosing the elements within parentheses. They provide a way to 419 | group related data together and are commonly used to represent data that should remain constant 420 | throughout the program's execution. The elements in a tuple can be accessed using indexing, 421 | similar to lists. However, since tuples are immutable, you cannot add, remove, or modify 422 | elements once the tuple is created, which makes them suitable for situations where data 423 | integrity and protection against accidental changes are desired. Tuples are commonly used to 424 | return multiple values from functions, as dictionary keys (since they are immutable), and as 425 | elements of sets, where only immutable objects are allowed. 426 |
427 |
431 |
432 | # Creating a tuple
433 | my_tuple = (1, 2, 3, 'apple', 'banana')
434 |
435 | # Accessing elements in the tuple
436 | print("Element at index 0:", my_tuple[0])
437 | # Output: Element at index 0: 1
438 | print("Element at index 3:", my_tuple[3])
439 | # Output: Element at index 3: apple
440 |
441 | # Length of the tuple
442 | length_of_tuple = len(my_tuple)
443 | print("Length of the tuple:", length_of_tuple)
444 | # Output: Length of the tuple: 5
445 |
446 | # Iterating over the tuple
447 | print("All elements in the tuple:")
448 | for item in my_tuple:
449 | print(item)
450 | # Output:
451 | # 1
452 | # 2
453 | # 3
454 | # apple
455 | # banana
456 |
457 |
458 |
459 |
460 |
461 | In this example, my_tuple is a simple tuple containing 463 | integer and string elements. We access elements using indexing, find the length of the tuple, 464 | and iterate through all the elements using a for loop. Once a tuple is created, its elements 465 | cannot be changed, added, or removed, ensuring its immutability. Tuples are useful for scenarios 466 | where you need to store a fixed set of related data that should not be altered during the 467 | program's execution. 468 |
469 | 470 |Let's demonstrate the immutable property of tuples by 473 | attempting to modify a tuple after it has been created. This will result in a TypeError since 475 | tuples cannot be changed once they are defined.
476 |
478 |
479 | # Creating a tuple
480 | my_tuple = (1, 2, 3)
481 |
482 | # Attempting to modify the tuple
483 | try:
484 | my_tuple[1] = 10
485 | # Trying to change the element at index 1 to 10
486 | except TypeError as e:
487 | print("TypeError:", e)
488 | # Output: TypeError: 'tuple' object does not support item assignment
489 |
490 |
491 |
492 |
493 |
494 | As shown in the code, when we try to modify the element 496 | at index 1 of the tuple my_tuple, Python raises a TypeError with the message " 'tuple' object 497 | does not support item assignment." This error indicates that tuples are immutable and cannot be 498 | changed after creation. 499 |
500 | 501 |This is in contrast to lists, where you can modify, 502 | add, or remove elements freely. The immutability of tuples makes them suitable for situations 503 | where you want to ensure data integrity and protect against unintended changes to the data. 504 |
505 | 506 | 507 | 508 |In Python, a dictionary is an unordered, mutable 514 | collection of key-value pairs, where each key must be unique. Dictionaries are represented using 515 | curly braces { } and allow for efficient data retrieval and 516 | modification based on their keys. 517 | Each key is associated with a value, and this association is known as a key-value pair. Keys in 518 | dictionaries must be immutable objects, such as strings, numbers, or tuples, while values can be 519 | of any data type. Dictionaries are widely used in Python for tasks that involve data lookup and 520 | storage, mapping relationships between different elements, and efficiently organizing and 521 | managing data. 522 |
523 |
527 |
528 | # Creating a dictionary
529 | my_dict = {
530 | 'name': 'John',
531 | 'age': 30,
532 | 'city': 'New York',
533 | 'email': 'john@example.com'
534 | }
535 |
536 | # Accessing values using keys
537 | print("Name:", my_dict['name']) # Output: Name: John
538 | print("Age:", my_dict['age']) # Output: Age: 30
539 | print("City:", my_dict['city']) # Output: City: New York
540 | print("Email:", my_dict['email']) # Output: Email: john@example.com
541 |
542 | # Modifying values in the dictionary
543 | my_dict['age'] = 32
544 | print("Modified dictionary:", my_dict)
545 | # Output: Modified dictionary:
546 | # {'name': 'John', 'age': 32, 'city': 'New York', 'email': 'john@example.com'}
547 |
548 | # Adding new key-value pairs to the dictionary
549 | my_dict['occupation'] = 'Engineer'
550 | print("Dictionary with new pair:", my_dict)
551 | # Output: Dictionary with new pair:
552 | # {'name': 'John', 'age': 32, 'city': 'New York',
553 | 'email': 'john@example.com', 'occupation': 'Engineer'}
554 |
555 | # Removing a key-value pair from the dictionary
556 | del my_dict['email']
557 | print("Dictionary after removing email:", my_dict)
558 | # Output: Dictionary after removing email:
559 | # {'name': 'John', 'age': 32, 'city': 'New York', 'occupation': 'Engineer'}
560 |
561 | # Length of the dictionary
562 | length_of_dict = len(my_dict)
563 | print("Length of the dictionary:", length_of_dict)
564 | # Output: Length of the dictionary: 4
565 |
566 |
567 |
568 |
569 |
570 | In this example, my_dict is a dictionary with key-value 572 | pairs representing various information about a person. We access values using their 573 | corresponding keys, modify values, add new key-value pairs, and remove key-value pairs using the 574 | del keyword. Dictionaries are versatile data structures that offer efficient lookup and 575 | manipulation based on their keys, making them valuable for organizing and managing data in 576 | Python programs. 577 |
578 |In Python, a set is an unordered, mutable collection of 582 | unique elements. Sets are represented using curly braces { } or 583 | the built-in `set()` function. 584 | Unlike lists or tuples, sets do not allow duplicate elements. When you create a set with 585 | duplicate items, Python automatically removes the duplicates, leaving only the unique elements. 586 | Sets are useful for tasks that involve membership tests, removing duplicates from sequences, and 587 | performing mathematical set operations like union, intersection, and difference. Additionally, 588 | since sets only contain unique elements, they are commonly used to find distinct elements in 589 | data collections.
590 |
594 |
595 | # Creating a set using curly braces
596 | my_set = {1, 2, 3, 4, 4, 5}
597 | # Note the duplicate element 4, which will be automatically removed
598 | print("Set using curly braces:", my_set)
599 | # Output: Set using curly braces: {1, 2, 3, 4, 5}
600 |
601 | # Creating a set using the set() function
602 | another_set = set([3, 4, 5, 6, 7])
603 | print("Set using set() function:", another_set)
604 | # Output: Set using set() function: {3, 4, 5, 6, 7}
605 |
606 | # Adding elements to the set
607 | my_set.add(6)
608 | my_set.add(7)
609 | print("Set after adding elements:", my_set)
610 | # Output: Set after adding elements: {1, 2, 3, 4, 5, 6, 7}
611 |
612 | # Removing elements from the set
613 | my_set.remove(5)
614 | print("Set after removing element 5:", my_set)
615 | # Output: Set after removing element 5: {1, 2, 3, 4, 6, 7}
616 |
617 | # Checking membership in the set
618 | print("Is 3 in the set?", 3 in my_set)
619 | # Output: Is 3 in the set? True
620 | print("Is 5 in the set?", 5 in my_set)
621 | # Output: Is 5 in the set? False
622 |
623 | # Set operations
624 | set_a = {1, 2, 3, 4, 5}
625 | set_b = {4, 5, 6, 7, 8}
626 |
627 | # Union of two sets
628 | union_set = set_a.union(set_b)
629 | print("Union of sets:", union_set)
630 | # Output: Union of sets: {1, 2, 3, 4, 5, 6, 7, 8}
631 |
632 | # Intersection of two sets
633 | intersection_set = set_a.intersection(set_b)
634 | print("Intersection of sets:", intersection_set)
635 | # Output: Intersection of sets: {4, 5}
636 |
637 | # Difference between two sets
638 | difference_set = set_a.difference(set_b)
639 | print("Difference of sets:", difference_set)
640 | # Output: Difference of sets: {1, 2, 3}
641 |
642 | # Removing all elements from the set
643 | my_set.clear()
644 | print("Set after clearing:", my_set)
645 | # Output: Set after clearing: set()
646 |
647 |
648 |
649 |
650 |
651 | In this code, we first create sets using curly braces 653 | and the set() function. We demonstrate adding and removing elements from the set, checking 654 | membership using the in keyword, and performing set operations like union, intersection, and 655 | difference. Sets are versatile data structures, especially useful when you need to handle unique 656 | elements and perform set operations efficiently. 657 |
658 |168 | An algorithm is a step-by-step set of instructions or a well-defined process designed to solve a 169 | specific problem or accomplish a task, often used in computer programming and other fields to achieve 170 | desired outcomes efficiently. 171 |
172 |When we'll pass the input to an Algorithm , it must give us an 195 | output and this should be a 196 | finite value . And for every programming language the output might be same for a particular input value 197 | .
198 |Implementing an algorithm may sound daunting, but it can be 205 | broken down into simple steps. Here's a beginner-friendly guide to help you get started :-
206 |Before you begin implementing an algorithm, it's 212 | essential to thoroughly understand the problem you're trying to solve. Clearly define the inputs 213 | and outputs, and consider any constraints that may impact the solution. Gather all the necessary 214 | information and ask questions to gain a comprehensive understanding of the problem at hand.
215 |Selecting the right algorithm is crucial for solving 220 | the problem efficiently. There are various algorithms available for different tasks, such as 221 | searching, sorting, or graph traversal. Research and choose an algorithm that fits your specific 222 | requirements and is well-suited to the nature of the problem.
223 |Algorithms can often be complex, so it's helpful to 228 | break them down into smaller, more manageable steps. This process involves understanding each 229 | step and how they work together to achieve the desired solution. Creating flowcharts or diagrams 230 | can be beneficial in visualizing the algorithm's workflow.
231 |Pseudo code is an intermediate step between 236 | understanding the algorithm and writing actual code. It involves writing the algorithm in 237 | human-readable terms, without worrying about the specific syntax of a programming language. 238 | Pseudo code helps to solidify the logic and approach before diving into the code.
239 |Once you have a clear understanding of the algorithm 244 | and have outlined it in pseudo code, it's time to choose a programming language for 245 | implementation. The choice of language depends on your familiarity with it and the requirements 246 | of your project. Popular languages include Python, Java, C++, and JavaScript.
247 |With the pseudo code as a guide, start translating it 252 | into actual code using your chosen programming language. Focus on implementing one step at a 253 | time and test each step thoroughly before proceeding. Building the code incrementally helps in 254 | identifying and fixing issues early on.
255 |Testing is a critical phase in the implementation 260 | process. Create test cases that cover various scenarios, including normal cases, edge cases, and 261 | possible errors. By testing rigorously, you can ensure that your algorithm produces accurate 262 | results under different conditions.
263 |If your code doesn't work as expected, use debugging 268 | techniques to identify and fix any errors. Additionally, consider optimizing your code to 269 | improve its efficiency, if necessary. Reducing time and memory complexity can make your 270 | algorithm more performant.
271 |Documentation is essential to explain the purpose of 276 | the code and the logic behind it. Add comments and detailed explanations within the code to make 277 | it understandable for yourself and other developers who may work on it in the future.
278 |After successfully implementing and testing your 283 | algorithm, integrate it into your project or application. Be prepared to maintain the code and 284 | make improvements based on user feedback or changing requirements. Software development is an 285 | iterative process, and continuous improvement is key to delivering reliable solutions.
286 |Remember that algorithm implementation requires practice and 289 | patience. By following these steps and learning from your experiences, you'll become more proficient in 290 | designing and implementing algorithms.
291 |Time complexity is a measure of how the running time of an 296 | algorithm increases with the size of its input data. It helps us understand the efficiency of an 297 | algorithm and how it scales as the problem size grows. Time complexity is usually expressed using big-O 298 | notation, which provides an upper bound on the growth rate of an algorithm's running time concerning the 299 | input size.
300 |Big-O notation, often written as O(f(n)), is a mathematical 303 | notation used to describe the upper bound of the growth rate of a function or an algorithm. In the 304 | context of time complexity, 'f(n)' represents the number of operations an algorithm performs concerning 305 | the size of its input 'n'. Big-O notation allows us to compare and analyze algorithms' efficiency and 306 | identify which algorithms are more scalable and better suited for larger data sets.
307 |Write a Python function to calculate the sum of elements in 310 | an array. Analyze the time complexity of the 311 | function and calculate its O notation. Provide a simple example demonstrating how the function performs 312 | with different array sizes.
313 |314 | Let's go step by step to implement the Python function to calculate the sum of elements in an 315 | array and then analyze its time complexity.
316 |317 | Step 1: Define the function and initialize the `total` variable to zero.
318 |
320 |
321 | def sum_array(arr):
322 | total = 0
323 |
324 |
325 |
326 | 329 | Step 2: Use a loop to iterate through each element in the array and add it to the `total`.
330 |
332 |
333 | for num in arr:
334 | total += num
335 |
336 |
337 |
338 | 341 | Step 3: Return the calculated sum.
342 |
344 |
345 | return total
346 |
347 |
348 |
349 | 351 | Now that we have implemented the function, let's analyze its time complexity and calculate the O 352 | notation.
353 |383 | Finally, let's provide a simple example demonstrating how the function performs with different array 384 | sizes :-
385 |
387 |
388 | arr = [1, 2, 3, 4, 5]
389 | print(sum_array(arr)) # Output: 15
390 |
391 |
392 |
393 | 395 | As the input array grows larger, the time taken by the `sum_array` function will increase linearly with 396 | the size of the array. For example, if the array has 1000 elements, the function will take approximately 397 | 1000 times longer to complete compared to an array with 10 elements. This demonstrates the linear time 398 | complexity of the function. 399 |
400 |Space complexity is a measure of how much additional memory or 405 | space an algorithm or program requires to solve a problem, based on the size of its input. It helps us 406 | understand the efficiency of an algorithm in terms of memory usage. Space complexity includes all the 407 | extra data structures and variables used during the execution of an algorithm, in addition to the input 408 | data. Similar to time complexity, space complexity is also analyzed using big-O notation to express the 409 | upper bound of the space required concerning the input size. Reducing space complexity is essential to 410 | optimize memory usage and improve the performance of algorithms, especially when dealing with large 411 | datasets or resource-constrained environments.
412 |Write a Python function that takes a list of integers as 415 | input and returns the count of unique elements in the list. You are required to solve this problem using 416 | additional space, and your implementation should aim for minimal space complexity. Analyze the space 417 | complexity of your solution and provide a simple example to demonstrate how the function works.
418 |To count the unique elements in the list while minimizing 419 | space usage, we can use a set data structure. A set is an unordered collection of unique elements. By 420 | converting the input list into a set, we automatically remove any duplicate elements. Then, we can 421 | return the size of the set, which represents the count of unique elements.
422 |
424 |
425 | def count_unique_elements(arr):
426 | unique_set = set(arr)
427 | return len(unique_set)
428 |
429 |
430 |
431 | Let's demonstrate the function with a simple example :
454 |
456 |
457 | arr = [3, 1, 4, 1, 5, 9, 2, 6, 5]
458 | print(count_unique_elements(arr)) # Output: 7
459 |
460 |
461 |
462 | In this example, the input list has 9 elements, but there are 464 | only 7 unique elements: [3, 1, 4, 5, 9, 2, 6]. The function will return 7 as the count of unique 465 | elements.
466 |Overall, by utilizing a set to remove duplicates and counting 467 | the size of the set, this solution efficiently finds the count of unique elements while optimizing space 468 | usage.
469 |165 | Python is a versatile programming language known for its simplicity 166 | and readability, making it an excellent choice for both beginners and 167 | experienced programmers. It provides an extensive set of libraries and 168 | frameworks that make development faster and more efficient. Moreover, 169 | Python's popularity has grown immensely over the years, making it one 170 | of the most widely used programming languages. 171 |
172 | 173 |174 | When it comes to Data Structures and Algorithms (DSA), Python offers a 175 | range of built-in data structures and comprehensive libraries that 176 | simplify the implementation of algorithms. These features, combined 177 | with Python's expressive syntax, make it an ideal language for working 178 | with DSA. 179 |
180 | 181 |182 | Let's explore some of the key aspects of Python programming and its relevance to DSA :- 183 |
184 | 185 |186 |
239 | Overall, Python's combination of simplicity, readability, powerful libraries, and vast community support makes 240 | it an excellent choice for implementing data structures and algorithms. Its ecosystem provides ample resources, 241 | tutorials, and documentation to support learning and mastering DSA using Python. 242 |
243 |
248 |
249 | print("Hello, World!")
250 |
251 |
252 |
253 |
254 | Variables are the name , given to a particular memory location. We've 264 | to follow some rule to declare a variable names in Python . Those are :-
265 |As Python is a Dynamically Typed programming language , we don't need to mention the data type of the 278 | variable . This will automatically detect that .
279 |We've some by default data-types in Python like,-
285 | 1) 286 | Integer 287 | 2) 288 | Float 289 | 3) 290 | Strings 291 | 4) 292 | Arrays 293 |To know a data-type of a variable , we can use type() 294 | function .
295 |In Python we've some Arithmetical Operators ,-
299 | 1) 300 | [+] 301 | To add two integers / floats / strings 302 |We've to use input() function to take inputs , from the users 326 | . By default the input() function stores the user input in string 327 | data-type format .
328 |
330 |
331 | def add():
332 | input1 = input("Enter Your first Number : ")
333 | input2 = input("Enter Your second Number : ")
334 |
335 | output = input1 + input2
336 | print("The result is " + output)
337 |
338 | add()
339 |
340 |
341 | This code will store your numbers as string data-type , so it will not add your numbers . But if you 344 | want to add them , you've to convert the data-type to string(str) to integer(int) . Let see how we can do that,- 345 |
346 |
348 |
349 | def add():
350 | input1 = int(input("Enter Your first Number : "))
351 | input2 = int(input("Enter Your second Number : "))
352 |
353 | output = input1 + input2
354 | print("The result is " + output)
355 |
356 | add()
357 |
358 |
359 |