Migrate to Zensical (#1869)

* Fix Russian Ruby code extraction.

* Add zensical configs.
This commit is contained in:
Yudong Jin
2026-03-29 05:41:25 +08:00
committed by GitHub
parent bc4c5ec414
commit 7a78369e4c
84 changed files with 1302 additions and 445 deletions

7
.gitignore vendored
View File

@@ -1,12 +1,7 @@
# macOS
.DS_Store .DS_Store
# editors
.vscode/ .vscode/
**/.idea /node_modules
# mkdocs files
.cache/
# build # build
/build /build

View File

@@ -9,6 +9,8 @@
{% set announcements = 'Welcome to contribute to Chinese-to-English translation! For more details, please refer to <a href="https://github.com/krahets/hello-algo/blob/main/en/CONTRIBUTING.md">CONTRIBUTING.md</a>.' %} {% set announcements = 'Welcome to contribute to Chinese-to-English translation! For more details, please refer to <a href="https://github.com/krahets/hello-algo/blob/main/en/CONTRIBUTING.md">CONTRIBUTING.md</a>.' %}
{% elif config.theme.language == 'ja' %} {% elif config.theme.language == 'ja' %}
{% set announcements = '日本語版審閱者を募集しています!詳細は <a href="https://github.com/krahets/hello-algo/blob/main/ja/CONTRIBUTING.md">CONTRIBUTING.md</a> を参照してください。' %} {% set announcements = '日本語版審閱者を募集しています!詳細は <a href="https://github.com/krahets/hello-algo/blob/main/ja/CONTRIBUTING.md">CONTRIBUTING.md</a> を参照してください。' %}
{% elif config.theme.language == 'ru' %}
{% set announcements = 'Приглашаем вас участвовать в развитии русской версии! Подробнее <a href="/ru/chapter_appendix/contribution/">здесь</a>.' %}
{% endif %} {% endif %}
<div class="banner-svg"> <div class="banner-svg">
<svg xmlns="http://www.w3.org/2000/svg" <svg xmlns="http://www.w3.org/2000/svg"
@@ -18,4 +20,4 @@
</svg> </svg>
<span>{{ announcements }}</span> <span>{{ announcements }}</span>
</div> </div>
{% endblock %} {% endblock %}

View File

@@ -1 +0,0 @@
comments.html

View File

@@ -0,0 +1,71 @@
{% if page.meta.comments %}
{% if config.theme.language == 'zh' %}
{% set comm = "欢迎在评论区留下你的见解、问题或建议" %}
{% set lang = "zh-CN" %}
{% elif config.theme.language == 'zh-Hant' %}
{% set comm = "歡迎在評論區留下你的見解、問題或建議" %}
{% set lang = "zh-TW" %}
{% elif config.theme.language == 'en' %}
{% set comm = "Feel free to drop your insights, questions or suggestions" %}
{% set lang = "en" %}
{% elif config.theme.language == 'ja' %}
{% set comm = "ご意見、ご質問、ご提案があればぜひコメントしてください" %}
{% set lang = "ja" %}
{% elif config.theme.language == 'ru' %}
{% set comm = "Оставляйте свои идеи, вопросы и предложения в комментариях" %}
{% set lang = "ru" %}
{% endif %}
<!-- Check-in button above comments -->
{% include "partials/checkin.html" ignore missing %}
<h5 align="center" id="__comments">{{ comm }}</h5>
<!-- Insert generated snippet here -->
<script
src="https://giscus.app/client.js"
data-repo="krahets/hello-algo"
data-repo-id="R_kgDOIXtSqw"
data-category="Announcements"
data-category-id="DIC_kwDOIXtSq84CSZk_"
data-mapping="pathname"
data-strict="1"
data-reactions-enabled="1"
data-emit-metadata="1"
data-input-position="top"
data-theme="light"
data-lang="{{ lang }}"
crossorigin="anonymous"
async
>
</script>
<!-- Synchronize Giscus theme with palette -->
<script>
var giscus = document.querySelector("script[src*=giscus]")
/* Set palette on initial load */
var palette = __md_get("__palette")
if (palette && typeof palette.color === "object") {
var theme = palette.color.scheme === "slate" ? "dark_dimmed" : "light"
giscus.setAttribute("data-theme", theme)
}
/* Register event handlers after documented loaded */
document.addEventListener("DOMContentLoaded", function() {
var ref = document.querySelector("[data-md-component=palette]")
ref.addEventListener("change", function() {
var palette = __md_get("__palette")
if (palette && typeof palette.color === "object") {
var theme = palette.color.scheme === "slate" ? "dark_dimmed" : "light"
/* Instruct Giscus to change theme */
var frame = document.querySelector(".giscus-frame")
frame.contentWindow.postMessage(
{ giscus: { setConfig: { theme } } },
"https://giscus.app"
)
}
})
})
</script>
{% endif %}

View File

@@ -0,0 +1,770 @@
/* Color Settings */
/* https://github.com/squidfunk/mkdocs-material/blob/6b5035f5580f97532d664e3d1babf5f320e88ee9/src/assets/stylesheets/main/_colors.scss */
/* https://squidfunk.github.io/mkdocs-material/setup/changing-the-colors/#custom-colors */
:root>* {
--md-primary-fg-color: #ffffff;
--md-primary-bg-color: #1d1d20;
--md-default-fg-color: #1d1d20;
--md-default-bg-color: #ffffff;
--md-body-bg-color: #22272e;
--md-header-bg-color: rgba(255, 255, 255, 0.6);
--md-code-fg-color: #1d1d20;
--md-code-bg-color: #f5f5f5;
--md-accent-fg-color: #999;
--md-typeset-color: #1d1d20;
--md-typeset-a-color: #349890;
--md-typeset-btn-color: #55aea6;
--md-typeset-btn-hover-color: #52bbb1;
--md-admonition-icon--pythontutor: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19.14 7.5A2.86 2.86 0 0 1 22 10.36v3.78A2.86 2.86 0 0 1 19.14 17H12c0 .39.32.96.71.96H17v1.68a2.86 2.86 0 0 1-2.86 2.86H9.86A2.86 2.86 0 0 1 7 19.64v-3.75a2.85 2.85 0 0 1 2.86-2.85h5.25a2.85 2.85 0 0 0 2.85-2.86V7.5h1.18m-4.28 11.79c-.4 0-.72.3-.72.89 0 .59.32.71.72.71a.71.71 0 0 0 .71-.71c0-.59-.32-.89-.71-.89m-10-1.79A2.86 2.86 0 0 1 2 14.64v-3.78A2.86 2.86 0 0 1 4.86 8H12c0-.39-.32-.96-.71-.96H7V5.36A2.86 2.86 0 0 1 9.86 2.5h4.28A2.86 2.86 0 0 1 17 5.36v3.75a2.85 2.85 0 0 1-2.86 2.85H8.89a2.85 2.85 0 0 0-2.85 2.86v2.68H4.86M9.14 5.71c.4 0 .72-.3.72-.89 0-.59-.32-.71-.72-.71-.39 0-.71.12-.71.71s.32.89.71.89Z"/></svg>');
--md-admonition-pythontutor-color: #eee;
}
[data-md-color-scheme="slate"] {
--theme-dark-base: #1E1E1E;
--theme-dark-mantle: #1A1A1A;
--theme-dark-crust: #171717;
--hero-starfield-bg-color: var(--theme-dark-base);
--md-primary-fg-color: var(--theme-dark-base);
--md-primary-bg-color: #adbac7;
--md-default-fg-color: #adbac7;
--md-default-bg-color: var(--theme-dark-base);
--md-body-bg-color: var(--theme-dark-mantle);
--md-header-bg-color: rgba(26, 26, 26, 0.8);
--md-code-fg-color: #adbac7;
--md-code-bg-color: var(--theme-dark-crust);
--md-accent-fg-color: #aaa;
--md-footer-fg-color: #adbac7;
--md-footer-bg-color: var(--theme-dark-mantle);
--md-typeset-color: #adbac7;
--md-typeset-a-color: #52bbb1;
--md-typeset-btn-color: #52bbb1;
--md-typeset-btn-hover-color: #55aea6;
--md-admonition-pythontutor-color: var(--theme-dark-crust);
}
[data-md-color-scheme="slate"][data-md-color-primary="black"],
[data-md-color-scheme="slate"][data-md-color-primary="white"] {
--md-typeset-a-color: #52bbb1;
}
[data-md-color-scheme="slate"] .md-footer,
[data-md-color-scheme="slate"] .md-footer__inner {
background-color: var(--theme-dark-mantle);
color: var(--md-footer-fg-color);
}
[data-md-color-scheme="slate"] .md-footer-meta {
background-color: var(--theme-dark-crust);
color: var(--md-footer-fg-color);
}
[data-md-color-scheme="slate"] .md-footer__link {
background-color: var(--theme-dark-crust);
color: var(--md-footer-fg-color);
}
[data-md-color-scheme="slate"] .md-footer__link:hover {
background-color: var(--theme-dark-base);
}
[data-md-color-scheme="slate"] .md-footer__title,
[data-md-color-scheme="slate"] .md-footer__direction,
[data-md-color-scheme="slate"] .md-footer__button,
[data-md-color-scheme="slate"] .md-copyright,
[data-md-color-scheme="slate"] .md-copyright a,
[data-md-color-scheme="slate"] .md-social,
[data-md-color-scheme="slate"] .md-social__link {
color: var(--md-footer-fg-color);
}
/* https://github.com/squidfunk/mkdocs-material/issues/4832#issuecomment-1374891676 */
.md-nav__link[for] {
color: var(--md-default-fg-color) !important;
}
/* Figure class */
.animation-figure {
border-radius: 0.3rem;
display: block;
margin: 0 auto;
box-shadow: var(--md-shadow-z2);
}
/* Cover image class */
.cover-image {
width: 28rem;
height: auto;
border-radius: 0.3rem;
display: block;
margin: 0 auto;
box-shadow: var(--md-shadow-z2);
}
/* Center Markdown Tables (requires md_in_html extension) */
.center-table {
text-align: center;
}
/* Reset alignment for table cells */
.md-typeset .center-table :is(td, th):not([align]) {
text-align: initial;
}
/* Font size */
.md-typeset {
font-size: 0.75rem;
line-height: 1.5;
}
.md-typeset pre {
font-size: 0.95em;
}
/* Markdown Header */
/* https://github.com/squidfunk/mkdocs-material/blob/dcab57dd1cced4b77875c1aa1b53467c62709d31/src/assets/stylesheets/main/_typeset.scss */
.md-typeset h1 {
font-weight: 400;
color: var(--md-default-fg-color);
}
.md-typeset h2 {
font-weight: 400;
}
.md-typeset h3 {
font-weight: 500;
}
.md-typeset h5 {
text-transform: none;
}
.md-typeset a:hover {
color: var(--md-typeset-a-color);
text-decoration: underline;
}
.md-typeset code {
border-radius: 0.2rem;
}
.highlight span.filename {
font-weight: normal;
}
/* font-family setting for Win10 */
body {
--md-text-font-family: -apple-system, BlinkMacSystemFont,
var(--md-text-font, _), Helvetica, Arial, sans-serif;
--md-code-font-family: var(--md-code-font, _), SFMono-Regular, Consolas, Menlo,
-apple-system, BlinkMacSystemFont, var(--md-text-font, _), monospace;
}
/* max height of code block */
/* https://github.com/squidfunk/mkdocs-material/issues/3444 */
.md-typeset pre>code {
max-height: 25rem;
}
/* Keep code block scrollbar hover neutral instead of accent-colored */
.md-typeset pre>code:hover {
scrollbar-color: var(--md-default-fg-color--lighter) transparent;
}
.md-typeset pre>code::-webkit-scrollbar-thumb:hover {
background-color: var(--md-default-fg-color--lighter);
}
/* Make the picture not glare in dark theme */
[data-md-color-scheme="slate"] .md-typeset img,
[data-md-color-scheme="slate"] .md-typeset svg,
[data-md-color-scheme="slate"] .md-typeset video {
filter: brightness(0.85) invert(0.05);
}
/* landing page */
.header-img-div {
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto;
width: 100%;
/* Default to full width */
}
/* Admonition for python tutor */
.md-typeset .admonition.pythontutor,
.md-typeset details.pythontutor {
border-color: var(--md-default-fg-color--lightest);
margin-top: 0;
margin-bottom: 1.5625em;
}
.md-typeset .pythontutor>.admonition-title,
.md-typeset .pythontutor>summary {
background-color: var(--md-code-bg-color);
}
.md-typeset .pythontutor>.admonition-title::before,
.md-typeset .pythontutor>summary::before {
background-color: rgb(55, 118, 171);
-webkit-mask-image: var(--md-admonition-icon--pythontutor);
mask-image: var(--md-admonition-icon--pythontutor);
}
/* code block tabs */
.md-typeset .tabbed-labels>label {
font-size: 0.61rem;
}
.md-typeset .tabbed-labels--linked>label>a {
padding: .78125em 1.0em .625em;
}
/* header banner */
.md-banner {
background-color: var(--md-code-bg-color);
color: var(--md-default-fg-color);
font-size: 0.75rem;
}
.md-banner .banner-svg svg {
margin-right: 0.3rem;
height: 0.63rem;
fill: var(--md-default-fg-color);
}
.pythontutor-iframe {
width: 125%;
height: 125%;
max-width: 125% !important;
max-height: 125% !important;
transform: scale(0.8);
transform-origin: top left;
border: none;
}
/* landing page container */
.home-div {
width: 100%;
height: auto;
display: flex;
justify-content: center;
align-items: center;
background-color: var(--md-default-bg-color);
color: var(--md-default-fg-color);
font-size: 0.9rem;
padding: 3em 2em;
text-align: center;
}
.section-content {
width: 100%;
height: auto;
max-width: 70vw;
}
/* rounded button */
.rounded-button {
display: inline-flex;
align-items: center;
justify-content: center;
border-radius: 10em;
margin: 0 0.1em;
padding: 0.6em 1.3em;
border: none;
background-color: var(--md-typeset-btn-color);
color: var(--md-primary-fg-color) !important;
text-align: center;
text-decoration: none;
cursor: pointer;
}
.rounded-button:hover {
background-color: var(--md-typeset-btn-hover-color);
}
.rounded-button span {
margin: 0;
margin-bottom: 0.07em;
white-space: nowrap;
}
.rounded-button svg {
fill: var(--md-primary-fg-color);
width: auto;
height: 1.2em;
margin-right: 0.5em;
}
/* device image */
.device-on-hover {
width: auto;
transition: transform 0.3s ease-in-out, filter 0.3s ease-in-out;
}
a:hover .device-on-hover {
filter: drop-shadow(0 0 0.2rem rgba(0, 0, 0, 0.15));
transform: scale(1.01);
}
/* text button */
.reading-media {
display: flex;
justify-content: center;
align-items: flex-end;
height: 32vw;
}
.media-block {
height: 100%;
margin: 0 0.2em;
}
.text-button {
width: auto;
color: var(--md-typeset-btn-color);
text-decoration: none;
text-align: center;
margin: 2.7em auto;
}
.text-button span {
white-space: nowrap;
}
.text-button svg {
display: inline-block;
fill: var(--md-typeset-btn-color);
width: auto;
height: 0.9em;
background-size: cover;
padding-top: 0.17em;
margin-left: 0.15em;
}
a:hover .text-button span {
text-decoration: underline;
}
/* hero image */
.hero-div {
height: min(84vh, 75vw);
width: min(112vh, 100vw);
margin: 0 auto;
margin-top: -2.4rem;
padding: 0;
position: relative;
font-size: min(1.8vh, 2.5vw);
font-weight: normal;
}
.hero-bg {
height: 100%;
width: 100%;
object-fit: cover;
position: absolute;
}
/* hover on the planets */
.hero-div>a>img {
width: auto;
position: absolute;
transition: transform 0.3s ease-in-out, filter 0.3s ease-in-out;
}
.hero-div>a>span {
margin: 0;
position: absolute;
transform: translateX(-50%) translateY(-50%);
white-space: nowrap;
/* prevent line breaks */
color: white;
}
.hero-div>a:hover>img {
filter: brightness(1.15) saturate(1.1) drop-shadow(0 0 0.5rem rgba(255, 255, 255, 0.2));
transform: scale(1.03);
}
.hero-div>a:hover>span {
text-decoration: underline;
color: var(--md-typeset-btn-color);
}
.heading-div {
width: 100%;
position: absolute;
transform: translateX(-50%);
left: 50%;
bottom: min(2vh, 3vw);
pointer-events: none;
color: #fff;
}
/* code badge */
.code-badge {
width: 100%;
height: auto;
margin: 1em auto;
}
.code-badge img {
height: 1.07em;
width: auto;
}
/* brief intro */
.intro-container {
display: flex;
align-items: center;
margin: 2em auto;
}
.intro-image {
flex-shrink: 0;
flex-grow: 0;
width: 50%;
border-radius: 0.5em;
box-shadow: var(--md-shadow-z2);
}
.intro-text {
flex-grow: 1;
/* fill the space */
display: flex;
flex-direction: column;
justify-content: center;
text-align: left;
align-items: flex-start;
width: fit-content;
margin: 2em;
}
.intro-text>div {
align-self: flex-start;
width: auto;
margin: 0 auto;
}
.endor-text {
width: 50%;
}
.intro-quote {
color: var(--md-accent-fg-color);
font-weight: bold;
}
/* contributors table */
.profile-div {
display: flex;
flex-wrap: wrap;
justify-content: center;
max-width: 40em;
margin: 1em auto;
}
.profile-cell {
flex: 1 1 15%;
margin: 1em 0;
text-align: center;
}
.profile-img {
width: 5em;
border-radius: 50%;
margin-bottom: 0.5em;
}
.translator-profile-div {
gap: 0.5em;
}
.translator-profile-cell {
flex: 0 0 auto;
margin: 0.5em 0;
min-width: 8.5em;
}
.giscus-container {
width: 40em;
max-width: 100%;
margin: 0 auto;
}
/* Hide navigation */
@media screen and (max-width: 76.25em) {
.section-content {
max-width: 95vw;
}
.reading-media {
height: 33vw;
}
.contrib-image {
width: 100%;
}
}
/* mobile devices */
@media screen and (max-width: 60em) {
.home-div {
font-size: 0.75rem;
}
.hero-div {
margin-top: -4rem;
}
.intro-container {
flex-direction: column;
}
.intro-text {
width: auto;
order: 2;
margin: 0 auto;
}
.endor-text {
width: auto;
margin: 0 auto;
}
.intro-image {
width: 100%;
order: 1;
margin-bottom: 1em;
}
.text-button {
margin: 0.7em auto;
}
.profile-cell {
flex: 1 1 30%;
}
}
.video-container {
position: relative;
padding-bottom: 56.25%;
/* 16:9 */
height: 0;
}
.video-container iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
/* starfield */
.starfield {
position: absolute;
width: 100%;
height: 100%;
z-index: 0;
background-color: var(--hero-starfield-bg-color, transparent);
}
.starfield-origin {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
/* Zensical-specific adjustments merged into the main stylesheet. */
:root>* {
--md-accent-fg-color: var(--md-typeset-a-color);
--md-admonition-pythontutor-color: var(--md-code-bg-color);
--hello-algo-sidebar-width: 13rem;
}
[data-md-color-scheme="slate"] {
--md-accent-fg-color: var(--md-typeset-a-color);
--md-admonition-pythontutor-color: var(--md-code-bg-color);
--md-body-bg-color: var(--md-default-bg-color);
--md-default-bg-color--light: rgb(30 30 30 / 0.8);
}
[data-md-color-scheme="slate"] .md-typeset details.pythontutor[open]> :not(summary),
[data-md-color-scheme="slate"] .md-typeset details.pythontutor[open]> :not(summary) :is(p, li, strong, em, sub, sup, code, a) {
background-color: #f5f5f5;
color: #1d1d20;
}
body {
background-color: var(--md-default-bg-color);
}
html:has(body[data-md-color-scheme="slate"]) {
background-color: #1e1e1e;
}
html:has(body[data-md-color-scheme="default"]) {
background-color: #ffffff;
}
.home-div[data-md-color-scheme="default"],
.home-div[data-md-color-scheme="default"] h1,
.home-div[data-md-color-scheme="default"] h2,
.home-div[data-md-color-scheme="default"] h3,
.home-div[data-md-color-scheme="default"] h4,
.home-div[data-md-color-scheme="default"] h5,
.home-div[data-md-color-scheme="default"] h6 {
color: var(--md-default-fg-color);
}
.home-div[data-md-color-scheme="slate"],
.home-div[data-md-color-scheme="slate"] h1,
.home-div[data-md-color-scheme="slate"] h2,
.home-div[data-md-color-scheme="slate"] h3,
.home-div[data-md-color-scheme="slate"] h4,
.home-div[data-md-color-scheme="slate"] h5,
.home-div[data-md-color-scheme="slate"] h6 {
color: var(--md-default-fg-color);
}
.home-div .intro-quote {
color: var(--md-default-fg-color--light) !important;
}
.reading-media+p {
margin-top: 1em !important;
}
.md-typeset .admonition-title:before,
.md-typeset summary:before,
.md-typeset summary:after {
top: 50%;
}
.md-typeset .admonition-title:before,
.md-typeset summary:before {
transform: translateY(-50%);
}
.md-typeset summary:after {
transform: translateY(-50%) rotate(0deg);
}
.md-typeset details[open]>summary:after {
transform: translateY(-50%) rotate(90deg);
}
.md-nav__link[for] {
color: inherit !important;
}
.md-nav__link[for].md-nav__link--active {
color: var(--md-accent-fg-color) !important;
}
@media screen and (min-width: 76.25em) {
.md-grid {
max-width: calc(61rem + 2 * (var(--hello-algo-sidebar-width) - 12.1rem));
}
.md-sidebar--primary,
.md-sidebar--secondary {
width: var(--hello-algo-sidebar-width);
}
[dir="ltr"] .md-sidebar__inner {
padding-right: calc(100% - (var(--hello-algo-sidebar-width) - 0.6rem));
}
[dir="rtl"] .md-sidebar__inner {
padding-left: calc(100% - (var(--hello-algo-sidebar-width) - 0.6rem));
}
}
.md-sidebar--primary .md-sidebar__scrollwrap {
scrollbar-color: var(--md-default-fg-color--lighter) transparent;
}
.md-sidebar--primary .md-sidebar__scrollwrap::-webkit-scrollbar-thumb,
.md-sidebar--primary .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover {
background-color: var(--md-default-fg-color--lighter);
}
.md-footer,
.md-footer__inner,
.md-footer-meta,
.md-footer__link,
.md-footer__link:hover {
background-color: var(--md-default-bg-color);
}
.md-footer {
border-top: 0.05rem solid var(--md-default-fg-color--lightest);
}
[data-md-color-scheme="slate"] .md-footer,
[data-md-color-scheme="slate"] .md-footer__inner,
[data-md-color-scheme="slate"] .md-footer-meta,
[data-md-color-scheme="slate"] .md-footer__link,
[data-md-color-scheme="slate"] .md-footer__link:hover {
background-color: var(--md-default-bg-color);
}
.md-banner {
background-color: var(--md-default-bg-color);
}
.md-typeset .admonition.pythontutor,
.md-typeset details.pythontutor,
.md-typeset .pythontutor>.admonition-title,
.md-typeset .pythontutor>summary {
background-color: var(--md-code-bg-color);
}
.md-typeset .pythontutor>.admonition-title::before,
.md-typeset .pythontutor>summary::before,
.md-typeset .pythontutor>summary::after {
top: 50%;
}
.md-typeset .pythontutor>.admonition-title::before,
.md-typeset .pythontutor>summary::before {
transform: translateY(-50%);
}
.md-typeset .pythontutor>summary::after {
transform: translateY(-50%) rotate(0deg);
}
.md-typeset details[open].pythontutor>summary::after {
transform: translateY(-50%) rotate(90deg);
}
.md-typeset a:not(.md-button) {
text-decoration: none;
}
.md-typeset a:not(.md-button):hover,
.md-typeset a:not(.md-button):focus-visible {
text-decoration: underline;
}

View File

@@ -0,0 +1,20 @@
[project]
extra_css = [
"stylesheets/extra.css",
]
[project.theme]
features = [
"content.action.edit",
"content.code.annotate",
"content.code.copy",
"content.tabs.link",
"content.tooltips",
"navigation.indexes",
"navigation.top",
"navigation.tracking",
"search.highlight",
"search.share",
"search.suggest",
"toc.follow",
]

View File

@@ -4,7 +4,7 @@ Created Time: 2024-03-18
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end =end
# ## Случайный доступ к элементу ### ### Случайный доступ к элементу ###
def random_access(nums) def random_access(nums)
# Случайным образом выбрать число из интервала [0, nums.length) # Случайным образом выбрать число из интервала [0, nums.length)
random_index = Random.rand(0...nums.length) random_index = Random.rand(0...nums.length)
@@ -14,9 +14,9 @@ def random_access(nums)
end end
# ## Увеличить длину массива ### ### Увеличить длину массива ###
# Обратите внимание: Array в Ruby является динамическим массивом и может быть расширен напрямую # Обратите внимание: Array в Ruby является динамическим массивом и может расширяться напрямую
# Для удобства обучения эта функция рассматривает Array как массив неизменяемой длины # Для удобства обучения в этой функции Array рассматривается как массив неизменяемой длины
def extend(nums, enlarge) def extend(nums, enlarge)
# Инициализировать массив увеличенной длины # Инициализировать массив увеличенной длины
res = Array.new(nums.length + enlarge, 0) res = Array.new(nums.length + enlarge, 0)
@@ -30,7 +30,7 @@ def extend(nums, enlarge)
res res
end end
# ## Вставка элемента num по индексу index в массив ### ### Вставка элемента num по индексу index в массив ###
def insert(nums, num, index) def insert(nums, num, index)
# Сдвинуть элемент с индексом index и все последующие элементы на одну позицию назад # Сдвинуть элемент с индексом index и все последующие элементы на одну позицию назад
for i in (nums.length - 1).downto(index + 1) for i in (nums.length - 1).downto(index + 1)
@@ -42,7 +42,7 @@ def insert(nums, num, index)
end end
# ## Удаление элемента по индексу index ### ### Удаление элемента по индексу index ###
def remove(nums, index) def remove(nums, index)
# Сдвинуть все элементы после индекса index на одну позицию вперед # Сдвинуть все элементы после индекса index на одну позицию вперед
for i in index...(nums.length - 1) for i in index...(nums.length - 1)
@@ -50,7 +50,7 @@ def remove(nums, index)
end end
end end
# ## Обход массива ### ### Обход массива ###
def traverse(nums) def traverse(nums)
count = 0 count = 0
@@ -65,7 +65,7 @@ def traverse(nums)
end end
end end
# ## Поиск заданного элемента в массиве ### ### Поиск заданного элемента в массиве ###
def find(nums, target) def find(nums, target)
for i in 0...nums.length for i in 0...nums.length
return i if nums[i] == target return i if nums[i] == target

View File

@@ -7,15 +7,15 @@ Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
require_relative '../utils/list_node' require_relative '../utils/list_node'
require_relative '../utils/print_util' require_relative '../utils/print_util'
# ## Вставка узла _p после узла n0 в связном списке ### ### Вставка узла _p после узла n0 в связном списке ###
# В Ruby `p` встроенная функция, а `P` — константа, поэтому вместо этого можно использовать `_p` # В Ruby `p` является встроенной функцией, а `P` — константой, поэтому вместо них можно использовать `_p`
def insert(n0, _p) def insert(n0, _p)
n1 = n0.next n1 = n0.next
_p.next = n1 _p.next = n1
n0.next = _p n0.next = _p
end end
# ## Удаление первого узла после узла n0 в связном списке ### ### Удаление первого узла после узла n0 в связном списке ###
def remove(n0) def remove(n0)
return if n0.next.nil? return if n0.next.nil?
@@ -25,7 +25,7 @@ def remove(n0)
n0.next = n1 n0.next = n1
end end
# ## Доступ к узлу связного списка по индексу index ### ### Доступ к узлу связного списка по индексу index ###
def access(head, index) def access(head, index)
for i in 0...index for i in 0...index
return nil if head.nil? return nil if head.nil?
@@ -35,7 +35,7 @@ def access(head, index)
head head
end end
# ## Поиск первого узла со значением target в связном списке ### ### Поиск первого узла со значением target в связном списке ###
def find(head, target) def find(head, target)
index = 0 index = 0
while head while head

View File

@@ -4,12 +4,12 @@ Created Time: 2024-03-18
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end =end
# ## Класс списка ### ### Класс списка ###
class MyList class MyList
attr_reader :size # Получить длину списка (текущее число элементов) attr_reader :size # Получить длину списка (текущее число элементов)
attr_reader :capacity # Получить вместимость списка attr_reader :capacity # Получить вместимость списка
# ## Конструктор ### ### Конструктор ###
def initialize def initialize
@capacity = 10 @capacity = 10
@size = 0 @size = 0
@@ -17,20 +17,20 @@ class MyList
@arr = Array.new(capacity) @arr = Array.new(capacity)
end end
# ## Доступ к элементу ### ### Доступ к элементу ###
def get(index) def get(index)
# Если индекс выходит за границы, выбрасывается исключение; далее аналогично # Если индекс выходит за границы, выбрасывается исключение; далее аналогично
raise IndexError, "индекс выходит за границы" if index < 0 || index >= size raise IndexError, "индекс выходит за границы" if index < 0 || index >= size
@arr[index] @arr[index]
end end
# ## Доступ к элементу ### ### Доступ к элементу ###
def set(index, num) def set(index, num)
raise IndexError, "индекс выходит за границы" if index < 0 || index >= size raise IndexError, "индекс выходит за границы" if index < 0 || index >= size
@arr[index] = num @arr[index] = num
end end
# ## Добавление элемента в конец ### ### Добавление элемента в конец ###
def add(num) def add(num)
# При превышении вместимости по числу элементов запускается расширение # При превышении вместимости по числу элементов запускается расширение
extend_capacity if size == capacity extend_capacity if size == capacity
@@ -40,7 +40,7 @@ class MyList
@size += 1 @size += 1
end end
# ## Вставка элемента в середину ### ### Вставка элемента в середину ###
def insert(index, num) def insert(index, num)
raise IndexError, "индекс выходит за границы" if index < 0 || index >= size raise IndexError, "индекс выходит за границы" if index < 0 || index >= size
@@ -57,7 +57,7 @@ class MyList
@size += 1 @size += 1
end end
# ## Удаление элемента ### ### Удаление элемента ###
def remove(index) def remove(index)
raise IndexError, "индекс выходит за границы" if index < 0 || index >= size raise IndexError, "индекс выходит за границы" if index < 0 || index >= size
num = @arr[index] num = @arr[index]
@@ -74,7 +74,7 @@ class MyList
num num
end end
# ## Расширение списка ### ### Расширение списка ###
def extend_capacity def extend_capacity
# Создать новый массив длиной в extend_ratio раз больше исходного и скопировать в него исходный массив # Создать новый массив длиной в extend_ratio раз больше исходного и скопировать в него исходный массив
arr = @arr.dup + Array.new(capacity * (@extend_ratio - 1)) arr = @arr.dup + Array.new(capacity * (@extend_ratio - 1))
@@ -82,7 +82,7 @@ class MyList
@capacity = arr.length @capacity = arr.length
end end
# ## Преобразование списка в массив ### ### Преобразование списка в массив ###
def to_array def to_array
sz = size sz = size
# Преобразовывать только элементы списка в пределах фактической длины # Преобразовывать только элементы списка в пределах фактической длины

View File

@@ -4,7 +4,7 @@ Created Time: 2024-05-21
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end =end
# ## Алгоритм бэктрекинга: n ферзей ### ### Алгоритм бэктрекинга: n ферзей ###
def backtrack(row, n, state, res, cols, diags1, diags2) def backtrack(row, n, state, res, cols, diags1, diags2)
# Когда все строки уже обработаны, записать решение # Когда все строки уже обработаны, записать решение
if row == n if row == n
@@ -31,7 +31,7 @@ def backtrack(row, n, state, res, cols, diags1, diags2)
end end
end end
# ## Решить задачу о n ферзях ### ### Решить задачу о n ферзях ###
def n_queens(n) def n_queens(n)
# Инициализировать доску размера n*n, где 'Q' обозначает ферзя, а '#' — пустую клетку # Инициализировать доску размера n*n, где 'Q' обозначает ферзя, а '#' — пустую клетку
state = Array.new(n) { Array.new(n, "#") } state = Array.new(n) { Array.new(n, "#") }

View File

@@ -4,7 +4,7 @@ Created Time: 2024-05-22
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end =end
# ## Алгоритм бэктрекинга: все перестановки I ### ### Алгоритм бэктрекинга: все перестановки I ###
def backtrack(state, choices, selected, res) def backtrack(state, choices, selected, res)
# Когда длина состояния равна числу элементов, записать решение # Когда длина состояния равна числу элементов, записать решение
if state.length == choices.length if state.length == choices.length
@@ -28,7 +28,7 @@ def backtrack(state, choices, selected, res)
end end
end end
# ## Все перестановки I ### ### Все перестановки I ###
def permutations_i(nums) def permutations_i(nums)
res = [] res = []
backtrack([], nums, Array.new(nums.length, false), res) backtrack([], nums, Array.new(nums.length, false), res)

View File

@@ -4,7 +4,7 @@ Created Time: 2024-05-22
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end =end
# ## Алгоритм бэктрекинга: все перестановки II ### ### Алгоритм бэктрекинга: все перестановки II ###
def backtrack(state, choices, selected, res) def backtrack(state, choices, selected, res)
# Когда длина состояния равна числу элементов, записать решение # Когда длина состояния равна числу элементов, записать решение
if state.length == choices.length if state.length == choices.length
@@ -30,7 +30,7 @@ def backtrack(state, choices, selected, res)
end end
end end
# ## Все перестановки II ### ### Все перестановки II ###
def permutations_ii(nums) def permutations_ii(nums)
res = [] res = []
backtrack([], nums, Array.new(nums.length, false), res) backtrack([], nums, Array.new(nums.length, false), res)

View File

@@ -7,7 +7,7 @@ Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
require_relative '../utils/tree_node' require_relative '../utils/tree_node'
require_relative '../utils/print_util' require_relative '../utils/print_util'
# ## Предварительный обход: пример 1 ### ### Предварительный обход: пример 1 ###
def pre_order(root) def pre_order(root)
return unless root return unless root

View File

@@ -7,7 +7,7 @@ Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
require_relative '../utils/tree_node' require_relative '../utils/tree_node'
require_relative '../utils/print_util' require_relative '../utils/print_util'
# ## Предварительный обход: пример 2 ### ### Предварительный обход: пример 2 ###
def pre_order(root) def pre_order(root)
return unless root return unless root

View File

@@ -7,7 +7,7 @@ Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
require_relative '../utils/tree_node' require_relative '../utils/tree_node'
require_relative '../utils/print_util' require_relative '../utils/print_util'
# ## Предварительный обход: пример 3 ### ### Предварительный обход: пример 3 ###
def pre_order(root) def pre_order(root)
# Отсечение # Отсечение
return if !root || root.val == 3 return if !root || root.val == 3

View File

@@ -7,32 +7,32 @@ Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
require_relative '../utils/tree_node' require_relative '../utils/tree_node'
require_relative '../utils/print_util' require_relative '../utils/print_util'
# ## Проверка, является ли текущее состояние решением ### ### Проверка, является ли текущее состояние решением ###
def is_solution?(state) def is_solution?(state)
!state.empty? && state.last.val == 7 !state.empty? && state.last.val == 7
end end
# ## Записать решение ### ### Записать решение ###
def record_solution(state, res) def record_solution(state, res)
res << state.dup res << state.dup
end end
# ## Проверка допустимости этого выбора в текущем состоянии ### ### Проверка допустимости этого выбора в текущем состоянии ###
def is_valid?(state, choice) def is_valid?(state, choice)
choice && choice.val != 3 choice && choice.val != 3
end end
# ## Обновить состояние ### ### Обновить состояние ###
def make_choice(state, choice) def make_choice(state, choice)
state << choice state << choice
end end
# ## Восстановить состояние ### ### Восстановить состояние ###
def undo_choice(state, choice) def undo_choice(state, choice)
state.pop state.pop
end end
# ## Алгоритм бэктрекинга: пример 3 ### ### Алгоритм бэктрекинга: пример 3 ###
def backtrack(state, choices, res) def backtrack(state, choices, res)
# Проверить, является ли текущее состояние решением # Проверить, является ли текущее состояние решением
record_solution(state, res) if is_solution?(state) record_solution(state, res) if is_solution?(state)

View File

@@ -4,7 +4,7 @@ Created Time: 2024-05-22
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end =end
# ## Алгоритм бэктрекинга: сумма подмножеств I ### ### Алгоритм бэктрекинга: сумма подмножеств I ###
def backtrack(state, target, choices, start, res) def backtrack(state, target, choices, start, res)
# Если сумма подмножества равна target, записать решение # Если сумма подмножества равна target, записать решение
if target.zero? if target.zero?
@@ -26,7 +26,7 @@ def backtrack(state, target, choices, start, res)
end end
end end
# ## Решить задачу суммы подмножеств I ### ### Решить задачу суммы подмножеств I ###
def subset_sum_i(nums, target) def subset_sum_i(nums, target)
state = [] # Состояние (подмножество) state = [] # Состояние (подмножество)
nums.sort! # Отсортировать nums nums.sort! # Отсортировать nums

View File

@@ -4,7 +4,7 @@ Created Time: 2024-05-22
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end =end
# ## Алгоритм бэктрекинга: сумма подмножеств I ### ### Алгоритм бэктрекинга: сумма подмножеств I ###
def backtrack(state, target, total, choices, res) def backtrack(state, target, total, choices, res)
# Если сумма подмножества равна target, записать решение # Если сумма подмножества равна target, записать решение
if total == target if total == target

View File

@@ -4,7 +4,7 @@ Created Time: 2024-05-22
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end =end
# ## Алгоритм бэктрекинга: сумма подмножеств II ### ### Алгоритм бэктрекинга: сумма подмножеств II ###
def backtrack(state, target, choices, start, res) def backtrack(state, target, choices, start, res)
# Если сумма подмножества равна target, записать решение # Если сумма подмножества равна target, записать решение
if target.zero? if target.zero?
@@ -30,7 +30,7 @@ def backtrack(state, target, choices, start, res)
end end
end end
# ## Решить задачу суммы подмножеств II ### ### Решить задачу суммы подмножеств II ###
def subset_sum_ii(nums, target) def subset_sum_ii(nums, target)
state = [] # Состояние (подмножество) state = [] # Состояние (подмножество)
nums.sort! # Отсортировать nums nums.sort! # Отсортировать nums

View File

@@ -4,7 +4,7 @@ Created Time: 2024-03-30
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com), Cy (9738314@gmail.com) Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com), Cy (9738314@gmail.com)
=end =end
# ## Цикл for ### ### Цикл for ###
def for_loop(n) def for_loop(n)
res = 0 res = 0
@@ -16,7 +16,7 @@ def for_loop(n)
res res
end end
# ## Цикл while ### ### Цикл while ###
def while_loop(n) def while_loop(n)
res = 0 res = 0
i = 1 # Инициализация условной переменной i = 1 # Инициализация условной переменной
@@ -46,7 +46,7 @@ def while_loop_ii(n)
res res
end end
# ## Двойной цикл for ### ### Двойной цикл for ###
def nested_for_loop(n) def nested_for_loop(n)
res = "" res = ""

View File

@@ -4,7 +4,7 @@ Created Time: 2024-03-30
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end =end
# ## Рекурсия ### ### Рекурсия ###
def recur(n) def recur(n)
# Условие завершения # Условие завершения
return 1 if n == 1 return 1 if n == 1
@@ -14,7 +14,7 @@ def recur(n)
n + res n + res
end end
# ## Имитация рекурсии итерацией ### ### Имитация рекурсии итерацией ###
def for_loop_recur(n) def for_loop_recur(n)
# Использовать явный стек для имитации системного стека вызовов # Использовать явный стек для имитации системного стека вызовов
stack = [] stack = []
@@ -34,7 +34,7 @@ def for_loop_recur(n)
res res
end end
# ## Хвостовая рекурсия ### ### Хвостовая рекурсия ###
def tail_recur(n, res) def tail_recur(n, res)
# Условие завершения # Условие завершения
return res if n == 0 return res if n == 0
@@ -42,7 +42,7 @@ def tail_recur(n, res)
tail_recur(n - 1, res + n) tail_recur(n - 1, res + n)
end end
# ## Последовательность Фибоначчи: рекурсия ### ### Последовательность Фибоначчи: рекурсия ###
def fib(n) def fib(n)
# Условие завершения: f(1) = 0, f(2) = 1 # Условие завершения: f(1) = 0, f(2) = 1
return n - 1 if n == 1 || n == 2 return n - 1 if n == 1 || n == 2

View File

@@ -8,13 +8,13 @@ require_relative '../utils/list_node'
require_relative '../utils/tree_node' require_relative '../utils/tree_node'
require_relative '../utils/print_util' require_relative '../utils/print_util'
# ## Функция ### ### Функция ###
def function def function
# Выполнить некоторые операции # Выполнить некоторые операции
0 0
end end
# ## Постоянная сложность ### ### Постоянная сложность ###
def constant(n) def constant(n)
# Константы, переменные и объекты занимают O(1) памяти # Константы, переменные и объекты занимают O(1) памяти
a = 0 a = 0
@@ -27,7 +27,7 @@ def constant(n)
(0...n).each { function } (0...n).each { function }
end end
# ## Линейная сложность ### ### Линейная сложность ###
def linear(n) def linear(n)
# Список длины n занимает O(n) памяти # Список длины n занимает O(n) памяти
nums = Array.new(n, 0) nums = Array.new(n, 0)
@@ -46,7 +46,7 @@ def linear_recur(n)
linear_recur(n - 1) linear_recur(n - 1)
end end
# ## Квадратичная сложность ### ### Квадратичная сложность ###
def quadratic(n) def quadratic(n)
# Двумерный список занимает O(n^2) памяти # Двумерный список занимает O(n^2) памяти
Array.new(n) { Array.new(n, 0) } Array.new(n) { Array.new(n, 0) }

View File

@@ -4,7 +4,7 @@ Created Time: 2024-03-30
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end =end
# ## Постоянная сложность ### ### Постоянная сложность ###
def constant(n) def constant(n)
count = 0 count = 0
size = 100000 size = 100000
@@ -14,7 +14,7 @@ def constant(n)
count count
end end
# ## Линейная сложность ### ### Линейная сложность ###
def linear(n) def linear(n)
count = 0 count = 0
(0...n).each { count += 1 } (0...n).each { count += 1 }
@@ -33,7 +33,7 @@ def array_traversal(nums)
count count
end end
# ## Квадратичная сложность ### ### Квадратичная сложность ###
def quadratic(n) def quadratic(n)
count = 0 count = 0
@@ -106,7 +106,7 @@ def log_recur(n)
log_recur(n / 2) + 1 log_recur(n / 2) + 1
end end
# ## Линейно-логарифмическая сложность ### ### Линейно-логарифмическая сложность ###
def linear_log_recur(n) def linear_log_recur(n)
return 1 unless n > 1 return 1 unless n > 1

View File

@@ -4,7 +4,7 @@ Created Time: 2024-03-30
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end =end
# ## Создать массив с элементами: 1, 2, ..., n в случайном порядке ### ### Создать массив с элементами: 1, 2, ..., n в случайном порядке ###
def random_numbers(n) def random_numbers(n)
# Создать массив nums =: 1, 2, 3, ..., n # Создать массив nums =: 1, 2, 3, ..., n
nums = Array.new(n) { |i| i + 1 } nums = Array.new(n) { |i| i + 1 }
@@ -12,7 +12,7 @@ def random_numbers(n)
nums.shuffle! nums.shuffle!
end end
# ## Найти индекс числа 1 в массиве nums ### ### Найти индекс числа 1 в массиве nums ###
def find_one(nums) def find_one(nums)
for i in 0...nums.length for i in 0...nums.length
# Когда элемент 1 находится в начале массива, достигается лучшая временная сложность O(1) # Когда элемент 1 находится в начале массива, достигается лучшая временная сложность O(1)

View File

@@ -4,7 +4,7 @@ Created Time: 2024-05-13
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end =end
# ## Бинарный поиск: задача f(i, j) ### ### Бинарный поиск: задача f(i, j) ###
def dfs(nums, target, i, j) def dfs(nums, target, i, j)
# Если интервал пуст, целевой элемент отсутствует, вернуть -1 # Если интервал пуст, целевой элемент отсутствует, вернуть -1
return -1 if i > j return -1 if i > j
@@ -24,7 +24,7 @@ def dfs(nums, target, i, j)
end end
end end
# ## Бинарный поиск ### ### Бинарный поиск ###
def binary_search(nums, target) def binary_search(nums, target)
n = nums.length n = nums.length
# Решить задачу f(0, n-1) # Решить задачу f(0, n-1)

View File

@@ -7,7 +7,7 @@ Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
require_relative '../utils/tree_node' require_relative '../utils/tree_node'
require_relative '../utils/print_util' require_relative '../utils/print_util'
# ## Построить двоичное дерево: разделяй и властвуй ### ### Построить двоичное дерево: разделяй и властвуй ###
def dfs(preorder, inorder_map, i, l, r) def dfs(preorder, inorder_map, i, l, r)
# Завершить при пустом диапазоне поддерева # Завершить при пустом диапазоне поддерева
return if r - l < 0 return if r - l < 0
@@ -25,7 +25,7 @@ def dfs(preorder, inorder_map, i, l, r)
root root
end end
# ## Построить двоичное дерево ### ### Построить двоичное дерево ###
def build_tree(preorder, inorder) def build_tree(preorder, inorder)
# Инициализировать хеш-таблицу для хранения соответствия элементов inorder их индексам # Инициализировать хеш-таблицу для хранения соответствия элементов inorder их индексам
inorder_map = {} inorder_map = {}

View File

@@ -4,7 +4,7 @@ Created Time: 2024-05-13
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end =end
# ## Переместить один диск ### ### Переместить один диск ###
def move(src, tar) def move(src, tar)
# Снять диск с вершины src # Снять диск с вершины src
pan = src.pop pan = src.pop
@@ -12,7 +12,7 @@ def move(src, tar)
tar << pan tar << pan
end end
# ## Решить задачу Ханойской башни f(i) ### ### Решить задачу Ханойской башни f(i) ###
def dfs(i, src, buf, tar) def dfs(i, src, buf, tar)
# Если в src остался только один диск, сразу переместить его в tar # Если в src остался только один диск, сразу переместить его в tar
if i == 1 if i == 1
@@ -28,7 +28,7 @@ def dfs(i, src, buf, tar)
dfs(i - 1, buf, src, tar) dfs(i - 1, buf, src, tar)
end end
# ## Решить задачу Ханойской башни ### ### Решить задачу Ханойской башни ###
def solve_hanota(_A, _B, _C) def solve_hanota(_A, _B, _C)
n = _A.length n = _A.length
# Переместить верхние n дисков из A в C с помощью B # Переместить верхние n дисков из A в C с помощью B

View File

@@ -4,7 +4,7 @@ Created Time: 2024-05-29
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end =end
# ## Бэктрекинг ### ### Бэктрекинг ###
def backtrack(choices, state, n, res) def backtrack(choices, state, n, res)
# Когда подъем достигает n-й ступени, число вариантов увеличивается на 1 # Когда подъем достигает n-й ступени, число вариантов увеличивается на 1
res[0] += 1 if state == n res[0] += 1 if state == n
@@ -19,7 +19,7 @@ def backtrack(choices, state, n, res)
# Откат # Откат
end end
# ## Подъем по лестнице: бэктрекинг ### ### Подъем по лестнице: бэктрекинг ###
def climbing_stairs_backtrack(n) def climbing_stairs_backtrack(n)
choices = [1, 2] # Можно подняться на 1 или 2 ступени choices = [1, 2] # Можно подняться на 1 или 2 ступени
state = 0 # Начать подъем с 0-й ступени state = 0 # Начать подъем с 0-й ступени

View File

@@ -4,7 +4,7 @@ Created Time: 2024-05-29
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end =end
# ## Подъем по лестнице с ограничениями: динамическое программирование ### ### Подъем по лестнице с ограничениями: динамическое программирование ###
def climbing_stairs_constraint_dp(n) def climbing_stairs_constraint_dp(n)
return 1 if n == 1 || n == 2 return 1 if n == 1 || n == 2

View File

@@ -4,7 +4,7 @@ Created Time: 2024-05-29
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end =end
# ## Поиск ### ### Поиск ###
def dfs(i) def dfs(i)
# dp[1] и dp[2] уже известны, вернуть их # dp[1] и dp[2] уже известны, вернуть их
return i if i == 1 || i == 2 return i if i == 1 || i == 2
@@ -12,7 +12,7 @@ def dfs(i)
dfs(i - 1) + dfs(i - 2) dfs(i - 1) + dfs(i - 2)
end end
# ## Подъем по лестнице: поиск ### ### Подъем по лестнице: поиск ###
def climbing_stairs_dfs(n) def climbing_stairs_dfs(n)
dfs(n) dfs(n)
end end

View File

@@ -4,7 +4,7 @@ Created Time: 2024-05-29
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end =end
# ## Поиск с мемоизацией ### ### Поиск с мемоизацией ###
def dfs(i, mem) def dfs(i, mem)
# dp[1] и dp[2] уже известны, вернуть их # dp[1] и dp[2] уже известны, вернуть их
return i if i == 1 || i == 2 return i if i == 1 || i == 2
@@ -17,7 +17,7 @@ def dfs(i, mem)
mem[i] = count mem[i] = count
end end
# ## Подъем по лестнице: поиск с мемоизацией ### ### Подъем по лестнице: поиск с мемоизацией ###
def climbing_stairs_dfs_mem(n) def climbing_stairs_dfs_mem(n)
# mem[i] хранит число способов подняться на i-ю ступень, -1 означает отсутствие записи # mem[i] хранит число способов подняться на i-ю ступень, -1 означает отсутствие записи
mem = Array.new(n + 1, -1) mem = Array.new(n + 1, -1)

View File

@@ -4,7 +4,7 @@ Created Time: 2024-05-29
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end =end
# ## Подъем по лестнице: динамическое программирование ### ### Подъем по лестнице: динамическое программирование ###
def climbing_stairs_dp(n) def climbing_stairs_dp(n)
return n if n == 1 || n == 2 return n if n == 1 || n == 2
@@ -18,7 +18,7 @@ def climbing_stairs_dp(n)
dp[n] dp[n]
end end
# ## Подъем по лестнице: динамическое программирование с оптимизацией памяти ### ### Подъем по лестнице: динамическое программирование с оптимизацией памяти ###
def climbing_stairs_dp_comp(n) def climbing_stairs_dp_comp(n)
return n if n == 1 || n == 2 return n if n == 1 || n == 2

View File

@@ -4,7 +4,7 @@ Created Time: 2024-05-29
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end =end
# ## Размен монет: динамическое программирование ### ### Размен монет: динамическое программирование ###
def coin_change_dp(coins, amt) def coin_change_dp(coins, amt)
n = coins.length n = coins.length
_MAX = amt + 1 _MAX = amt + 1
@@ -27,7 +27,7 @@ def coin_change_dp(coins, amt)
dp[n][amt] != _MAX ? dp[n][amt] : -1 dp[n][amt] != _MAX ? dp[n][amt] : -1
end end
# ## Размен монет: динамическое программирование с оптимизацией памяти ### ### Размен монет: динамическое программирование с оптимизацией памяти ###
def coin_change_dp_comp(coins, amt) def coin_change_dp_comp(coins, amt)
n = coins.length n = coins.length
_MAX = amt + 1 _MAX = amt + 1

View File

@@ -4,7 +4,7 @@ Created Time: 2024-05-29
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end =end
# ## Размен монет II: динамическое программирование ### ### Размен монет II: динамическое программирование ###
def coin_change_ii_dp(coins, amt) def coin_change_ii_dp(coins, amt)
n = coins.length n = coins.length
# Инициализация таблицы dp # Инициализация таблицы dp
@@ -26,7 +26,7 @@ def coin_change_ii_dp(coins, amt)
dp[n][amt] dp[n][amt]
end end
# ## Размен монет II: динамическое программирование с оптимизацией памяти ### ### Размен монет II: динамическое программирование с оптимизацией памяти ###
def coin_change_ii_dp_comp(coins, amt) def coin_change_ii_dp_comp(coins, amt)
n = coins.length n = coins.length
# Инициализация таблицы dp # Инициализация таблицы dp

View File

@@ -4,7 +4,7 @@ Created Time: 2024-05-29
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end =end
# ## Редакционное расстояние: полный перебор ### ### Редакционное расстояние: полный перебор ###
def edit_distance_dfs(s, t, i, j) def edit_distance_dfs(s, t, i, j)
# Если s и t пусты, вернуть 0 # Если s и t пусты, вернуть 0
return 0 if i == 0 && j == 0 return 0 if i == 0 && j == 0
@@ -41,7 +41,7 @@ def edit_distance_dfs_mem(s, t, mem, i, j)
mem[i][j] = [insert, delete, replace].min + 1 mem[i][j] = [insert, delete, replace].min + 1
end end
# ## Редакционное расстояние: динамическое программирование ### ### Редакционное расстояние: динамическое программирование ###
def edit_distance_dp(s, t) def edit_distance_dp(s, t)
n, m = s.length, t.length n, m = s.length, t.length
dp = Array.new(n + 1) { Array.new(m + 1, 0) } dp = Array.new(n + 1) { Array.new(m + 1, 0) }
@@ -63,7 +63,7 @@ def edit_distance_dp(s, t)
dp[n][m] dp[n][m]
end end
# ## Редакционное расстояние: динамическое программирование с оптимизацией памяти ### ### Редакционное расстояние: динамическое программирование с оптимизацией памяти ###
def edit_distance_dp_comp(s, t) def edit_distance_dp_comp(s, t)
n, m = s.length, t.length n, m = s.length, t.length
dp = Array.new(m + 1, 0) dp = Array.new(m + 1, 0)

View File

@@ -4,7 +4,7 @@ Created Time: 2024-05-29
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end =end
# ## Рюкзак 0-1: полный перебор ### ### Рюкзак 0-1: полный перебор ###
def knapsack_dfs(wgt, val, i, c) def knapsack_dfs(wgt, val, i, c)
# Если все предметы уже рассмотрены или в рюкзаке не осталось места, вернуть стоимость 0 # Если все предметы уже рассмотрены или в рюкзаке не осталось места, вернуть стоимость 0
return 0 if i == 0 || c == 0 return 0 if i == 0 || c == 0
@@ -17,7 +17,7 @@ def knapsack_dfs(wgt, val, i, c)
[no, yes].max [no, yes].max
end end
# ## Рюкзак 0-1: поиск с мемоизацией ### ### Рюкзак 0-1: поиск с мемоизацией ###
def knapsack_dfs_mem(wgt, val, mem, i, c) def knapsack_dfs_mem(wgt, val, mem, i, c)
# Если все предметы уже рассмотрены или в рюкзаке не осталось места, вернуть стоимость 0 # Если все предметы уже рассмотрены или в рюкзаке не осталось места, вернуть стоимость 0
return 0 if i == 0 || c == 0 return 0 if i == 0 || c == 0
@@ -32,7 +32,7 @@ def knapsack_dfs_mem(wgt, val, mem, i, c)
mem[i][c] = [no, yes].max mem[i][c] = [no, yes].max
end end
# ## Рюкзак 0-1: динамическое программирование ### ### Рюкзак 0-1: динамическое программирование ###
def knapsack_dp(wgt, val, cap) def knapsack_dp(wgt, val, cap)
n = wgt.length n = wgt.length
# Инициализация таблицы dp # Инициализация таблицы dp
@@ -52,7 +52,7 @@ def knapsack_dp(wgt, val, cap)
dp[n][cap] dp[n][cap]
end end
# ## Рюкзак 0-1: динамическое программирование с оптимизацией памяти ### ### Рюкзак 0-1: динамическое программирование с оптимизацией памяти ###
def knapsack_dp_comp(wgt, val, cap) def knapsack_dp_comp(wgt, val, cap)
n = wgt.length n = wgt.length
# Инициализация таблицы dp # Инициализация таблицы dp

View File

@@ -4,7 +4,7 @@ Created Time: 2024-05-29
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end =end
# ## Минимальная стоимость подъема по лестнице: динамическое программирование ### ### Минимальная стоимость подъема по лестнице: динамическое программирование ###
def min_cost_climbing_stairs_dp(cost) def min_cost_climbing_stairs_dp(cost)
n = cost.length - 1 n = cost.length - 1
return cost[n] if n == 1 || n == 2 return cost[n] if n == 1 || n == 2

View File

@@ -4,7 +4,7 @@ Created Time: 2024-05-29
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end =end
# ## Минимальная сумма пути: полный перебор ### ### Минимальная сумма пути: полный перебор ###
def min_path_sum_dfs(grid, i, j) def min_path_sum_dfs(grid, i, j)
# Если это верхняя левая ячейка, завершить поиск # Если это верхняя левая ячейка, завершить поиск
return grid[i][j] if i == 0 && j == 0 return grid[i][j] if i == 0 && j == 0
@@ -17,7 +17,7 @@ def min_path_sum_dfs(grid, i, j)
[left, up].min + grid[i][j] [left, up].min + grid[i][j]
end end
# ## Минимальная сумма пути: поиск с мемоизацией ### ### Минимальная сумма пути: поиск с мемоизацией ###
def min_path_sum_dfs_mem(grid, mem, i, j) def min_path_sum_dfs_mem(grid, mem, i, j)
# Если это верхняя левая ячейка, завершить поиск # Если это верхняя левая ячейка, завершить поиск
return grid[0][0] if i == 0 && j == 0 return grid[0][0] if i == 0 && j == 0
@@ -32,7 +32,7 @@ def min_path_sum_dfs_mem(grid, mem, i, j)
mem[i][j] = [left, up].min + grid[i][j] mem[i][j] = [left, up].min + grid[i][j]
end end
# ## Минимальная сумма пути: динамическое программирование ### ### Минимальная сумма пути: динамическое программирование ###
def min_path_sum_dp(grid) def min_path_sum_dp(grid)
n, m = grid.length, grid.first.length n, m = grid.length, grid.first.length
# Инициализация таблицы dp # Инициализация таблицы dp
@@ -51,7 +51,7 @@ def min_path_sum_dp(grid)
dp[n -1][m -1] dp[n -1][m -1]
end end
# ## Минимальная сумма пути: динамическое программирование с оптимизацией памяти ### ### Минимальная сумма пути: динамическое программирование с оптимизацией памяти ###
def min_path_sum_dp_comp(grid) def min_path_sum_dp_comp(grid)
n, m = grid.length, grid.first.length n, m = grid.length, grid.first.length
# Инициализация таблицы dp # Инициализация таблицы dp

View File

@@ -4,7 +4,7 @@ Created Time: 2024-05-29
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end =end
# ## Полный рюкзак: динамическое программирование ### ### Полный рюкзак: динамическое программирование ###
def unbounded_knapsack_dp(wgt, val, cap) def unbounded_knapsack_dp(wgt, val, cap)
n = wgt.length n = wgt.length
# Инициализация таблицы dp # Инициализация таблицы dp

View File

@@ -6,11 +6,11 @@ Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
require_relative '../utils/vertex' require_relative '../utils/vertex'
# ## Класс неориентированного графа на основе списка смежности ### ### Класс неориентированного графа на основе списка смежности ###
class GraphAdjList class GraphAdjList
attr_reader :adj_list attr_reader :adj_list
# ## Конструктор ### ### Конструктор ###
def initialize(edges) def initialize(edges)
# Список смежности, где key — вершина, а value — все смежные ей вершины # Список смежности, где key — вершина, а value — все смежные ей вершины
@adj_list = {} @adj_list = {}
@@ -22,12 +22,12 @@ class GraphAdjList
end end
end end
# ## Получение числа вершин ### ### Получение числа вершин ###
def size def size
@adj_list.length @adj_list.length
end end
# ## Добавление ребра ### ### Добавление ребра ###
def add_edge(vet1, vet2) def add_edge(vet1, vet2)
raise ArgumentError if !@adj_list.include?(vet1) || !@adj_list.include?(vet2) raise ArgumentError if !@adj_list.include?(vet1) || !@adj_list.include?(vet2)
@@ -35,7 +35,7 @@ class GraphAdjList
@adj_list[vet2] << vet1 @adj_list[vet2] << vet1
end end
# ## Удаление ребра ### ### Удаление ребра ###
def remove_edge(vet1, vet2) def remove_edge(vet1, vet2)
raise ArgumentError if !@adj_list.include?(vet1) || !@adj_list.include?(vet2) raise ArgumentError if !@adj_list.include?(vet1) || !@adj_list.include?(vet2)
@@ -44,7 +44,7 @@ class GraphAdjList
@adj_list[vet2].delete(vet1) @adj_list[vet2].delete(vet1)
end end
# ## Добавление вершины ### ### Добавление вершины ###
def add_vertex(vet) def add_vertex(vet)
return if @adj_list.include?(vet) return if @adj_list.include?(vet)
@@ -52,7 +52,7 @@ class GraphAdjList
@adj_list[vet] = [] @adj_list[vet] = []
end end
# ## Удаление вершины ### ### Удаление вершины ###
def remove_vertex(vet) def remove_vertex(vet)
raise ArgumentError unless @adj_list.include?(vet) raise ArgumentError unless @adj_list.include?(vet)
@@ -64,7 +64,7 @@ class GraphAdjList
end end
end end
# ## Вывести список смежности ### ### Вывести список смежности ###
def __print__ def __print__
puts 'Список смежности =' puts 'Список смежности ='
for vertex in @adj_list for vertex in @adj_list

View File

@@ -6,10 +6,10 @@ Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
require_relative '../utils/print_util' require_relative '../utils/print_util'
# ## Класс неориентированного графа на основе матрицы смежности ### ### Класс неориентированного графа на основе матрицы смежности ###
class GraphAdjMat class GraphAdjMat
def initialize(vertices, edges) def initialize(vertices, edges)
# ## Конструктор ### ### Конструктор ###
# Список вершин: элементы представляют «значения вершин», а индексы — «индексы вершин» # Список вершин: элементы представляют «значения вершин», а индексы — «индексы вершин»
@vertices = [] @vertices = []
# Матрица смежности, где индексы строк и столбцов соответствуют «индексам вершин» # Матрица смежности, где индексы строк и столбцов соответствуют «индексам вершин»
@@ -21,12 +21,12 @@ class GraphAdjMat
edges.each { |e| add_edge(e[0], e[1]) } edges.each { |e| add_edge(e[0], e[1]) }
end end
# ## Получение числа вершин ### ### Получение числа вершин ###
def size def size
@vertices.length @vertices.length
end end
# ## Добавление вершины ### ### Добавление вершины ###
def add_vertex(val) def add_vertex(val)
n = size n = size
# Добавить значение новой вершины в список вершин # Добавить значение новой вершины в список вершин
@@ -38,7 +38,7 @@ class GraphAdjMat
@adj_mat.each { |row| row << 0 } @adj_mat.each { |row| row << 0 }
end end
# ## Удаление вершины ### ### Удаление вершины ###
def remove_vertex(index) def remove_vertex(index)
raise IndexError if index >= size raise IndexError if index >= size
@@ -50,7 +50,7 @@ class GraphAdjMat
@adj_mat.each { |row| row.delete_at(index) } @adj_mat.each { |row| row.delete_at(index) }
end end
# ## Добавление ребра ### ### Добавление ребра ###
def add_edge(i, j) def add_edge(i, j)
# Параметры i и j соответствуют индексам элементов vertices # Параметры i и j соответствуют индексам элементов vertices
# Обработка выхода индекса за границы и случая равенства # Обработка выхода индекса за границы и случая равенства
@@ -62,7 +62,7 @@ class GraphAdjMat
@adj_mat[j][i] = 1 @adj_mat[j][i] = 1
end end
# ## Удаление ребра ### ### Удаление ребра ###
def remove_edge(i, j) def remove_edge(i, j)
# Параметры i и j соответствуют индексам элементов vertices # Параметры i и j соответствуют индексам элементов vertices
# Обработка выхода индекса за границы и случая равенства # Обработка выхода индекса за границы и случая равенства
@@ -73,7 +73,7 @@ class GraphAdjMat
@adj_mat[j][i] = 0 @adj_mat[j][i] = 0
end end
# ## Вывести матрицу смежности ### ### Вывести матрицу смежности ###
def __print__ def __print__
puts "Список вершин = #{@vertices}" puts "Список вершин = #{@vertices}"
puts 'Матрица смежности =' puts 'Матрица смежности ='

View File

@@ -8,7 +8,7 @@ require 'set'
require_relative './graph_adjacency_list' require_relative './graph_adjacency_list'
require_relative '../utils/vertex' require_relative '../utils/vertex'
# ## Обход в ширину ### ### Обход в ширину ###
def graph_bfs(graph, start_vet) def graph_bfs(graph, start_vet)
# Использовать список смежности для представления графа, чтобы получать все смежные вершины заданной вершины # Использовать список смежности для представления графа, чтобы получать все смежные вершины заданной вершины
# Последовательность обхода вершин # Последовательность обхода вершин

View File

@@ -8,7 +8,7 @@ require 'set'
require_relative './graph_adjacency_list' require_relative './graph_adjacency_list'
require_relative '../utils/vertex' require_relative '../utils/vertex'
# ## Вспомогательная функция обхода в глубину ### ### Вспомогательная функция обхода в глубину ###
def dfs(graph, visited, res, vet) def dfs(graph, visited, res, vet)
res << vet # Отметить посещенную вершину res << vet # Отметить посещенную вершину
visited.add(vet) # Отметить эту вершину как посещенную visited.add(vet) # Отметить эту вершину как посещенную
@@ -20,7 +20,7 @@ def dfs(graph, visited, res, vet)
end end
end end
# ## Обход в глубину ### ### Обход в глубину ###
def graph_dfs(graph, start_vet) def graph_dfs(graph, start_vet)
# Использовать список смежности для представления графа, чтобы получать все смежные вершины заданной вершины # Использовать список смежности для представления графа, чтобы получать все смежные вершины заданной вершины
# Последовательность обхода вершин # Последовательность обхода вершин

View File

@@ -4,7 +4,7 @@ Created Time: 2024-05-07
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end =end
# ## Размен монет: жадный алгоритм ### ### Размен монет: жадный алгоритм ###
def coin_change_greedy(coins, amt) def coin_change_greedy(coins, amt)
# Предположить, что список coins упорядочен # Предположить, что список coins упорядочен
i = coins.length - 1 i = coins.length - 1

View File

@@ -4,7 +4,7 @@ Created Time: 2024-05-07
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end =end
# ## Предмет ### ### Предмет ###
class Item class Item
attr_accessor :w # Вес предмета attr_accessor :w # Вес предмета
attr_accessor :v # Стоимость предмета attr_accessor :v # Стоимость предмета
@@ -15,7 +15,7 @@ class Item
end end
end end
# ## Дробный рюкзак: жадный алгоритм ### ### Дробный рюкзак: жадный алгоритм ###
def fractional_knapsack(wgt, val, cap) def fractional_knapsack(wgt, val, cap)
# Создать список предметов с двумя свойствами: вес и стоимость # Создать список предметов с двумя свойствами: вес и стоимость
items = wgt.each_with_index.map { |w, i| Item.new(w, val[i]) } items = wgt.each_with_index.map { |w, i| Item.new(w, val[i]) }

View File

@@ -4,7 +4,7 @@ Created Time: 2024-05-07
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end =end
# ## Максимальная вместимость: жадный алгоритм ### ### Максимальная вместимость: жадный алгоритм ###
def max_capacity(ht) def max_capacity(ht)
# Инициализировать i и j так, чтобы они располагались по двум концам массива # Инициализировать i и j так, чтобы они располагались по двум концам массива
i, j = 0, ht.length - 1 i, j = 0, ht.length - 1

View File

@@ -4,7 +4,7 @@ Created Time: 2024-05-07
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end =end
# ## Максимальное произведение разрезания: жадный алгоритм ### ### Максимальное произведение разрезания: жадный алгоритм ###
def max_product_cutting(n) def max_product_cutting(n)
# Когда n <= 3, обязательно нужно выделить одну 1 # Когда n <= 3, обязательно нужно выделить одну 1
return 1 * (n - 1) if n <= 3 return 1 * (n - 1) if n <= 3

View File

@@ -4,7 +4,7 @@ Created Time: 2024-04-13
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end =end
# ## Пара ключ-значение ### ### Пара ключ-значение ###
class Pair class Pair
attr_accessor :key, :val attr_accessor :key, :val
@@ -14,20 +14,20 @@ class Pair
end end
end end
# ## Хеш-таблица на основе массива ### ### Хеш-таблица на основе массива ###
class ArrayHashMap class ArrayHashMap
# ## Конструктор ### ### Конструктор ###
def initialize def initialize
# Инициализировать массив, содержащий 100 корзин # Инициализировать массив, содержащий 100 корзин
@buckets = Array.new(100) @buckets = Array.new(100)
end end
# ## Хеш-функция ### ### Хеш-функция ###
def hash_func(key) def hash_func(key)
index = key % 100 index = key % 100
end end
# ## Операция поиска ### ### Операция поиска ###
def get(key) def get(key)
index = hash_func(key) index = hash_func(key)
pair = @buckets[index] pair = @buckets[index]
@@ -36,42 +36,42 @@ class ArrayHashMap
pair.val pair.val
end end
# ## Операция добавления ### ### Операция добавления ###
def put(key, val) def put(key, val)
pair = Pair.new(key, val) pair = Pair.new(key, val)
index = hash_func(key) index = hash_func(key)
@buckets[index] = pair @buckets[index] = pair
end end
# ## Операция удаления ### ### Операция удаления ###
def remove(key) def remove(key)
index = hash_func(key) index = hash_func(key)
# Присвоить nil, что означает удаление # Присвоить nil, что означает удаление
@buckets[index] = nil @buckets[index] = nil
end end
# ## Получить все пары ключ-значение ### ### Получить все пары ключ-значение ###
def entry_set def entry_set
result = [] result = []
@buckets.each { |pair| result << pair unless pair.nil? } @buckets.each { |pair| result << pair unless pair.nil? }
result result
end end
# ## Получить все ключи ### ### Получить все ключи ###
def key_set def key_set
result = [] result = []
@buckets.each { |pair| result << pair.key unless pair.nil? } @buckets.each { |pair| result << pair.key unless pair.nil? }
result result
end end
# ## Получить все значения ### ### Получить все значения ###
def value_set def value_set
result = [] result = []
@buckets.each { |pair| result << pair.val unless pair.nil? } @buckets.each { |pair| result << pair.val unless pair.nil? }
result result
end end
# ## Вывести хеш-таблицу ### ### Вывести хеш-таблицу ###
def print def print
@buckets.each { |pair| puts "#{pair.key} -> #{pair.val}" unless pair.nil? } @buckets.each { |pair| puts "#{pair.key} -> #{pair.val}" unless pair.nil? }
end end

View File

@@ -6,9 +6,9 @@ Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
require_relative './array_hash_map' require_relative './array_hash_map'
# ## Хеш-таблица с цепочками ### ### Хеш-таблица с цепочками ###
class HashMapChaining class HashMapChaining
# ## Конструктор ### ### Конструктор ###
def initialize def initialize
@size = 0 # Число пар ключ-значение @size = 0 # Число пар ключ-значение
@capacity = 4 # Вместимость хеш-таблицы @capacity = 4 # Вместимость хеш-таблицы
@@ -17,17 +17,17 @@ class HashMapChaining
@buckets = Array.new(@capacity) { [] } # Массив корзин @buckets = Array.new(@capacity) { [] } # Массив корзин
end end
# ## Хеш-функция ### ### Хеш-функция ###
def hash_func(key) def hash_func(key)
key % @capacity key % @capacity
end end
# ## Коэффициент загрузки ### ### Коэффициент загрузки ###
def load_factor def load_factor
@size / @capacity @size / @capacity
end end
# ## Операция поиска ### ### Операция поиска ###
def get(key) def get(key)
index = hash_func(key) index = hash_func(key)
bucket = @buckets[index] bucket = @buckets[index]
@@ -39,7 +39,7 @@ class HashMapChaining
nil nil
end end
# ## Операция добавления ### ### Операция добавления ###
def put(key, val) def put(key, val)
# Когда коэффициент загрузки превышает порог, выполнить расширение # Когда коэффициент загрузки превышает порог, выполнить расширение
extend if load_factor > @load_thres extend if load_factor > @load_thres
@@ -58,7 +58,7 @@ class HashMapChaining
@size += 1 @size += 1
end end
# ## Операция удаления ### ### Операция удаления ###
def remove(key) def remove(key)
index = hash_func(key) index = hash_func(key)
bucket = @buckets[index] bucket = @buckets[index]
@@ -72,7 +72,7 @@ class HashMapChaining
end end
end end
# ## Расширение хеш-таблицы ### ### Расширение хеш-таблицы ###
def extend def extend
# Временно сохранить исходную хеш-таблицу # Временно сохранить исходную хеш-таблицу
buckets = @buckets buckets = @buckets
@@ -88,7 +88,7 @@ class HashMapChaining
end end
end end
# ## Вывести хеш-таблицу ### ### Вывести хеш-таблицу ###
def print def print
for bucket in @buckets for bucket in @buckets
res = [] res = []

View File

@@ -6,11 +6,11 @@ Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
require_relative './array_hash_map' require_relative './array_hash_map'
# ## Хеш-таблица с открытой адресацией ### ### Хеш-таблица с открытой адресацией ###
class HashMapOpenAddressing class HashMapOpenAddressing
TOMBSTONE = Pair.new(-1, '-1') # Удалить метку TOMBSTONE = Pair.new(-1, '-1') # Удалить метку
# ## Конструктор ### ### Конструктор ###
def initialize def initialize
@size = 0 # Число пар ключ-значение @size = 0 # Число пар ключ-значение
@capacity = 4 # Вместимость хеш-таблицы @capacity = 4 # Вместимость хеш-таблицы
@@ -19,17 +19,17 @@ class HashMapOpenAddressing
@buckets = Array.new(@capacity) # Массив корзин @buckets = Array.new(@capacity) # Массив корзин
end end
# ## Хеш-функция ### ### Хеш-функция ###
def hash_func(key) def hash_func(key)
key % @capacity key % @capacity
end end
# ## Коэффициент загрузки ### ### Коэффициент загрузки ###
def load_factor def load_factor
@size / @capacity @size / @capacity
end end
# ## Найти индекс корзины, соответствующий key ### ### Найти индекс корзины, соответствующий key ###
def find_bucket(key) def find_bucket(key)
index = hash_func(key) index = hash_func(key)
first_tombstone = -1 first_tombstone = -1
@@ -54,7 +54,7 @@ class HashMapOpenAddressing
first_tombstone == -1 ? index : first_tombstone first_tombstone == -1 ? index : first_tombstone
end end
# ## Операция поиска ### ### Операция поиска ###
def get(key) def get(key)
# Найти индекс корзины, соответствующий key # Найти индекс корзины, соответствующий key
index = find_bucket(key) index = find_bucket(key)
@@ -64,7 +64,7 @@ class HashMapOpenAddressing
nil nil
end end
# ## Операция добавления ### ### Операция добавления ###
def put(key, val) def put(key, val)
# Когда коэффициент загрузки превышает порог, выполнить расширение # Когда коэффициент загрузки превышает порог, выполнить расширение
extend if load_factor > @load_thres extend if load_factor > @load_thres
@@ -80,7 +80,7 @@ class HashMapOpenAddressing
@size += 1 @size += 1
end end
# ## Операция удаления ### ### Операция удаления ###
def remove(key) def remove(key)
# Найти индекс корзины, соответствующий key # Найти индекс корзины, соответствующий key
index = find_bucket(key) index = find_bucket(key)
@@ -91,7 +91,7 @@ class HashMapOpenAddressing
end end
end end
# ## Расширение хеш-таблицы ### ### Расширение хеш-таблицы ###
def extend def extend
# Временно сохранить исходную хеш-таблицу # Временно сохранить исходную хеш-таблицу
buckets_tmp = @buckets buckets_tmp = @buckets
@@ -105,7 +105,7 @@ class HashMapOpenAddressing
end end
end end
# ## Вывести хеш-таблицу ### ### Вывести хеш-таблицу ###
def print def print
for pair in @buckets for pair in @buckets
if pair.nil? if pair.nil?

View File

@@ -4,7 +4,7 @@ Created Time: 2024-04-14
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end =end
# ## Аддитивное хеширование ### ### Аддитивное хеширование ###
def add_hash(key) def add_hash(key)
hash = 0 hash = 0
modulus = 1_000_000_007 modulus = 1_000_000_007
@@ -14,7 +14,7 @@ def add_hash(key)
hash % modulus hash % modulus
end end
# ## Мультипликативное хеширование ### ### Мультипликативное хеширование ###
def mul_hash(key) def mul_hash(key)
hash = 0 hash = 0
modulus = 1_000_000_007 modulus = 1_000_000_007
@@ -24,7 +24,7 @@ def mul_hash(key)
hash % modulus hash % modulus
end end
# ## XOR-хеширование ### ### XOR-хеширование ###
def xor_hash(key) def xor_hash(key)
hash = 0 hash = 0
modulus = 1_000_000_007 modulus = 1_000_000_007
@@ -34,7 +34,7 @@ def xor_hash(key)
hash % modulus hash % modulus
end end
# ## Хеширование с циклическим сдвигом ### ### Хеширование с циклическим сдвигом ###
def rot_hash(key) def rot_hash(key)
hash = 0 hash = 0
modulus = 1_000_000_007 modulus = 1_000_000_007

View File

@@ -6,11 +6,11 @@ Author: Blue Bean (lonnnnnnner@gmail.com)
require_relative '../utils/print_util' require_relative '../utils/print_util'
# ## Максимальная куча ### ### Максимальная куча ###
class MaxHeap class MaxHeap
attr_reader :max_heap attr_reader :max_heap
# ## Конструктор, строящий кучу по входному списку ### ### Конструктор, строящий кучу по входному списку ###
def initialize(nums) def initialize(nums)
# Добавить элементы списка в кучу без изменений # Добавить элементы списка в кучу без изменений
@max_heap = nums @max_heap = nums
@@ -20,42 +20,42 @@ class MaxHeap
end end
end end
# ## Получить индекс левого дочернего узла ### ### Получить индекс левого дочернего узла ###
def left(i) def left(i)
2 * i + 1 2 * i + 1
end end
# ## Получить индекс правого дочернего узла ### ### Получить индекс правого дочернего узла ###
def right(i) def right(i)
2 * i + 2 2 * i + 2
end end
# ## Получить индекс родительского узла ### ### Получить индекс родительского узла ###
def parent(i) def parent(i)
(i - 1) / 2 # Округление вниз при делении (i - 1) / 2 # Округление вниз при делении
end end
# ## Обмен элементов ### ### Обмен элементов ###
def swap(i, j) def swap(i, j)
@max_heap[i], @max_heap[j] = @max_heap[j], @max_heap[i] @max_heap[i], @max_heap[j] = @max_heap[j], @max_heap[i]
end end
# ## Получить размер кучи ### ### Получить размер кучи ###
def size def size
@max_heap.length @max_heap.length
end end
# ## Проверка, пуста ли куча ### ### Проверка, пуста ли куча ###
def is_empty? def is_empty?
size == 0 size == 0
end end
# ## Доступ к элементу на вершине кучи ### ### Доступ к элементу на вершине кучи ###
def peek def peek
@max_heap[0] @max_heap[0]
end end
# ## Добавление элемента в кучу ### ### Добавление элемента в кучу ###
def push(val) def push(val)
# Добавление узла # Добавление узла
@max_heap << val @max_heap << val
@@ -63,7 +63,7 @@ class MaxHeap
sift_up(size - 1) sift_up(size - 1)
end end
# ## Начиная с узла i, выполнить просеивание снизу вверх ### ### Начиная с узла i, выполнить просеивание снизу вверх ###
def sift_up(i) def sift_up(i)
loop do loop do
# Получение родительского узла для узла i # Получение родительского узла для узла i
@@ -77,7 +77,7 @@ class MaxHeap
end end
end end
# ## Извлечение элемента из кучи ### ### Извлечение элемента из кучи ###
def pop def pop
# Обработка пустого случая # Обработка пустого случая
raise IndexError, "куча пуста" if is_empty? raise IndexError, "куча пуста" if is_empty?
@@ -91,7 +91,7 @@ class MaxHeap
val val
end end
# ## Начиная с узла i, выполнить просеивание сверху вниз ### ### Начиная с узла i, выполнить просеивание сверху вниз ###
def sift_down(i) def sift_down(i)
loop do loop do
# Определить узел с максимальным значением среди i, l и r и обозначить его как ma # Определить узел с максимальным значением среди i, l и r и обозначить его как ma

View File

@@ -6,31 +6,31 @@ Author: Blue Bean (lonnnnnnner@gmail.com)
require_relative "./my_heap" require_relative "./my_heap"
# ## Добавление элемента в кучу ### ### Добавление элемента в кучу ###
def push_min_heap(heap, val) def push_min_heap(heap, val)
# Инвертировать знак элемента # Инвертировать знак элемента
heap.push(-val) heap.push(-val)
end end
# ## Извлечение элемента из кучи ### ### Извлечение элемента из кучи ###
def pop_min_heap(heap) def pop_min_heap(heap)
# Инвертировать знак элемента # Инвертировать знак элемента
-heap.pop -heap.pop
end end
# ## Доступ к элементу на вершине кучи ### ### Доступ к элементу на вершине кучи ###
def peek_min_heap(heap) def peek_min_heap(heap)
# Инвертировать знак элемента # Инвертировать знак элемента
-heap.peek -heap.peek
end end
# ## Извлечение элементов из кучи ### ### Извлечение элементов из кучи ###
def get_min_heap(heap) def get_min_heap(heap)
# Инвертировать все элементы кучи # Инвертировать все элементы кучи
heap.max_heap.map { |x| -x } heap.max_heap.map { |x| -x }
end end
# ## Поиск k наибольших элементов массива с помощью кучи ### ### Поиск k наибольших элементов массива с помощью кучи ###
def top_k_heap(nums, k) def top_k_heap(nums, k)
# Инициализация минимальной кучи # Инициализация минимальной кучи
# Обратите внимание: мы инвертируем все элементы кучи, чтобы с помощью максимальной кучи имитировать минимальную # Обратите внимание: мы инвертируем все элементы кучи, чтобы с помощью максимальной кучи имитировать минимальную

View File

@@ -4,7 +4,7 @@ Created Time: 2024-04-09
Author: Blue Bean (lonnnnnnner@gmail.com) Author: Blue Bean (lonnnnnnner@gmail.com)
=end =end
# ## Бинарный поиск (двусторонне замкнутый интервал) ### ### Бинарный поиск (двусторонне замкнутый интервал) ###
def binary_search(nums, target) def binary_search(nums, target)
# Инициализировать двусторонне замкнутый интервал [0, n-1], то есть i и j указывают на первый и последний элементы массива соответственно # Инициализировать двусторонне замкнутый интервал [0, n-1], то есть i и j указывают на первый и последний элементы массива соответственно
i, j = 0, nums.length - 1 i, j = 0, nums.length - 1
@@ -26,7 +26,7 @@ def binary_search(nums, target)
-1 # Целевой элемент не найден, вернуть -1 -1 # Целевой элемент не найден, вернуть -1
end end
# ## Бинарный поиск (лево замкнутый, право открытый интервал) ### ### Бинарный поиск (лево замкнутый, право открытый интервал) ###
def binary_search_lcro(nums, target) def binary_search_lcro(nums, target)
# Инициализировать лево замкнутый, право открытый интервал [0, n), то есть i и j указывают на первый элемент массива и позицию сразу за последним элементом соответственно # Инициализировать лево замкнутый, право открытый интервал [0, n), то есть i и j указывают на первый элемент массива и позицию сразу за последним элементом соответственно
i, j = 0, nums.length i, j = 0, nums.length

View File

@@ -6,7 +6,7 @@ Author: Blue Bean (lonnnnnnner@gmail.com)
require_relative './binary_search_insertion' require_relative './binary_search_insertion'
# ## Бинарный поиск самого левого target ### ### Бинарный поиск самого левого target ###
def binary_search_left_edge(nums, target) def binary_search_left_edge(nums, target)
# Эквивалентно поиску точки вставки target # Эквивалентно поиску точки вставки target
i = binary_search_insertion(nums, target) i = binary_search_insertion(nums, target)
@@ -17,7 +17,7 @@ def binary_search_left_edge(nums, target)
i # Найти target и вернуть индекс i i # Найти target и вернуть индекс i
end end
# ## Бинарный поиск самого правого target ### ### Бинарный поиск самого правого target ###
def binary_search_right_edge(nums, target) def binary_search_right_edge(nums, target)
# Преобразовать задачу в поиск самого левого target + 1 # Преобразовать задачу в поиск самого левого target + 1
i = binary_search_insertion(nums, target + 1) i = binary_search_insertion(nums, target + 1)

View File

@@ -4,7 +4,7 @@ Created Time: 2024-04-09
Author: Blue Bean (lonnnnnnner@gmail.com) Author: Blue Bean (lonnnnnnner@gmail.com)
=end =end
# ## Бинарный поиск точки вставки (без повторяющихся элементов) ### ### Бинарный поиск точки вставки (без повторяющихся элементов) ###
def binary_search_insertion_simple(nums, target) def binary_search_insertion_simple(nums, target)
# Инициализировать двусторонне замкнутый интервал [0, n-1] # Инициализировать двусторонне замкнутый интервал [0, n-1]
i, j = 0, nums.length - 1 i, j = 0, nums.length - 1
@@ -25,7 +25,7 @@ def binary_search_insertion_simple(nums, target)
i # target не найден, вернуть точку вставки i i # target не найден, вернуть точку вставки i
end end
# ## Бинарный поиск точки вставки (с повторяющимися элементами) ### ### Бинарный поиск точки вставки (с повторяющимися элементами) ###
def binary_search_insertion(nums, target) def binary_search_insertion(nums, target)
# Инициализировать двусторонне замкнутый интервал [0, n-1] # Инициализировать двусторонне замкнутый интервал [0, n-1]
i, j = 0, nums.length - 1 i, j = 0, nums.length - 1

View File

@@ -6,14 +6,14 @@ Author: Blue Bean (lonnnnnnner@gmail.com)
require_relative '../utils/list_node' require_relative '../utils/list_node'
# ## Хеш-поиск (массив) ### ### Хеш-поиск (массив) ###
def hashing_search_array(hmap, target) def hashing_search_array(hmap, target)
# key хеш-таблицы: целевой элемент, value: индекс # key хеш-таблицы: целевой элемент, value: индекс
# Если такого key нет в хеш-таблице, вернуть -1 # Если такого key нет в хеш-таблице, вернуть -1
hmap[target] || -1 hmap[target] || -1
end end
# ## Хеш-поиск (связный список) ### ### Хеш-поиск (связный список) ###
def hashing_search_linkedlist(hmap, target) def hashing_search_linkedlist(hmap, target)
# key хеш-таблицы: целевой элемент, value: объект узла # key хеш-таблицы: целевой элемент, value: объект узла
# Если такого key нет в хеш-таблице, вернуть None # Если такого key нет в хеш-таблице, вернуть None

View File

@@ -6,7 +6,7 @@ Author: Blue Bean (lonnnnnnner@gmail.com)
require_relative '../utils/list_node' require_relative '../utils/list_node'
# ## Линейный поиск (массив) ### ### Линейный поиск (массив) ###
def linear_search_array(nums, target) def linear_search_array(nums, target)
# Обход массива # Обход массива
for i in 0...nums.length for i in 0...nums.length
@@ -16,7 +16,7 @@ def linear_search_array(nums, target)
-1 # Целевой элемент не найден, вернуть -1 -1 # Целевой элемент не найден, вернуть -1
end end
# ## Линейный поиск (связный список) ### ### Линейный поиск (связный список) ###
def linear_search_linkedlist(head, target) def linear_search_linkedlist(head, target)
# Обойти связный список # Обойти связный список
while head while head

View File

@@ -4,7 +4,7 @@ Created Time: 2024-04-09
Author: Blue Bean (lonnnnnnner@gmail.com) Author: Blue Bean (lonnnnnnner@gmail.com)
=end =end
# ## Метод 1: полный перебор ### ### Метод 1: полный перебор ###
def two_sum_brute_force(nums, target) def two_sum_brute_force(nums, target)
# Два вложенных цикла, временная сложность O(n^2) # Два вложенных цикла, временная сложность O(n^2)
for i in 0...(nums.length - 1) for i in 0...(nums.length - 1)
@@ -16,7 +16,7 @@ def two_sum_brute_force(nums, target)
[] []
end end
# ## Метод 2: вспомогательная хеш-таблица ### ### Метод 2: вспомогательная хеш-таблица ###
def two_sum_hash_table(nums, target) def two_sum_hash_table(nums, target)
# Вспомогательная хеш-таблица, пространственная сложность O(n) # Вспомогательная хеш-таблица, пространственная сложность O(n)
dic = {} dic = {}

View File

@@ -4,7 +4,7 @@ Created Time: 2024-05-02
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end =end
# ## Пузырьковая сортировка ### ### Пузырьковая сортировка ###
def bubble_sort(nums) def bubble_sort(nums)
n = nums.length n = nums.length
# Внешний цикл: неотсортированный диапазон [0, i] # Внешний цикл: неотсортированный диапазон [0, i]

View File

@@ -4,7 +4,7 @@ Created Time: 2024-04-17
Author: Martin Xu (martin.xus@gmail.com) Author: Martin Xu (martin.xus@gmail.com)
=end =end
# ## Сортировка корзинами ### ### Сортировка корзинами ###
def bucket_sort(nums) def bucket_sort(nums)
# Инициализировать k = n/2 корзин, предполагая распределение 2 элементов в каждую корзину # Инициализировать k = n/2 корзин, предполагая распределение 2 элементов в каждую корзину
k = nums.length / 2 k = nums.length / 2

View File

@@ -4,7 +4,7 @@ Created Time: 2024-05-02
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end =end
# ## Сортировка подсчетом ### ### Сортировка подсчетом ###
def counting_sort_naive(nums) def counting_sort_naive(nums)
# Простая реализация, не подходит для сортировки объектов # Простая реализация, не подходит для сортировки объектов
# 1. Найти максимальный элемент массива m # 1. Найти максимальный элемент массива m
@@ -24,7 +24,7 @@ def counting_sort_naive(nums)
end end
end end
# ## Сортировка подсчетом ### ### Сортировка подсчетом ###
def counting_sort(nums) def counting_sort(nums)
# Полная реализация, позволяет сортировать объекты и является стабильной сортировкой # Полная реализация, позволяет сортировать объекты и является стабильной сортировкой
# 1. Найти максимальный элемент массива m # 1. Найти максимальный элемент массива m

View File

@@ -4,7 +4,7 @@ Created Time: 2024-04-10
Author: junminhong (junminhong1110@gmail.com) Author: junminhong (junminhong1110@gmail.com)
=end =end
# ## Длина кучи равна n; начиная с узла i, выполнить просеивание сверху вниз ### ### Длина кучи равна n; начиная с узла i, выполнить просеивание сверху вниз ###
def sift_down(nums, n, i) def sift_down(nums, n, i)
while true while true
# Определить узел с максимальным значением среди i, l и r и обозначить его как ma # Определить узел с максимальным значением среди i, l и r и обозначить его как ma
@@ -22,7 +22,7 @@ def sift_down(nums, n, i)
end end
end end
# ## Сортировка кучей ### ### Сортировка кучей ###
def heap_sort(nums) def heap_sort(nums)
# Построение кучи: выполнить heapify для всех узлов, кроме листовых # Построение кучи: выполнить heapify для всех узлов, кроме листовых
(nums.length / 2 - 1).downto(0) do |i| (nums.length / 2 - 1).downto(0) do |i|

View File

@@ -4,7 +4,7 @@ Created Time: 2024-04-02
Author: Cy (3739004@gmail.com), Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) Author: Cy (3739004@gmail.com), Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end =end
# ## Сортировка вставками ### ### Сортировка вставками ###
def insertion_sort(nums) def insertion_sort(nums)
n = nums.length n = nums.length
# Внешний цикл: отсортированный диапазон [0, i-1] # Внешний цикл: отсортированный диапазон [0, i-1]

View File

@@ -4,7 +4,7 @@ Created Time: 2024-04-10
Author: junminhong (junminhong1110@gmail.com) Author: junminhong (junminhong1110@gmail.com)
=end =end
# ## Слияние левого и правого подмассивов ### ### Слияние левого и правого подмассивов ###
def merge(nums, left, mid, right) def merge(nums, left, mid, right)
# Интервал левого подмассива: [left, mid], правого подмассива: [mid+1, right] # Интервал левого подмассива: [left, mid], правого подмассива: [mid+1, right]
# Создать временный массив tmp для хранения результата слияния # Создать временный массив tmp для хранения результата слияния
@@ -39,7 +39,7 @@ def merge(nums, left, mid, right)
end end
end end
# ## Сортировка слиянием ### ### Сортировка слиянием ###
def merge_sort(nums, left, right) def merge_sort(nums, left, right)
# Условие завершения # Условие завершения
# Когда длина подмассива равна 1, рекурсия завершается # Когда длина подмассива равна 1, рекурсия завершается

View File

@@ -4,10 +4,10 @@ Created Time: 2024-04-01
Author: Cy (3739004@gmail.com), Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) Author: Cy (3739004@gmail.com), Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end =end
# ## Класс быстрой сортировки ### ### Класс быстрой сортировки ###
class QuickSort class QuickSort
class << self class << self
# ## Разбиение с опорными указателями ### ### Разбиение с опорными указателями ###
def partition(nums, left, right) def partition(nums, left, right)
# Взять nums[left] в качестве опорного элемента # Взять nums[left] в качестве опорного элемента
i, j = left, right i, j = left, right
@@ -26,7 +26,7 @@ class QuickSort
i # Вернуть индекс опорного элемента i # Вернуть индекс опорного элемента
end end
# ## Класс быстрой сортировки ### ### Класс быстрой сортировки ###
def quick_sort(nums, left, right) def quick_sort(nums, left, right)
# Рекурсивно обрабатывать, пока длина подмассива не станет равной 1 # Рекурсивно обрабатывать, пока длина подмассива не станет равной 1
if left < right if left < right
@@ -44,7 +44,7 @@ end
# ## Класс быстрой сортировки (оптимизация медианой) ### # ## Класс быстрой сортировки (оптимизация медианой) ###
class QuickSortMedian class QuickSortMedian
class << self class << self
# ## Выбрать медиану из трех кандидатов ### ### Выбрать медиану из трех кандидатов ###
def median_three(nums, left, mid, right) def median_three(nums, left, mid, right)
# Выбрать медиану из трех кандидатов # Выбрать медиану из трех кандидатов
_l, _m, _r = nums[left], nums[mid], nums[right] _l, _m, _r = nums[left], nums[mid], nums[right]
@@ -77,7 +77,7 @@ class QuickSortMedian
i # Вернуть индекс опорного элемента i # Вернуть индекс опорного элемента
end end
# ## Быстрая сортировка ### ### Быстрая сортировка ###
def quick_sort(nums, left, right) def quick_sort(nums, left, right)
# Рекурсивно обрабатывать, пока длина подмассива не станет равной 1 # Рекурсивно обрабатывать, пока длина подмассива не станет равной 1
if left < right if left < right
@@ -95,7 +95,7 @@ end
# ## Класс быстрой сортировки (оптимизация глубины рекурсии) ### # ## Класс быстрой сортировки (оптимизация глубины рекурсии) ###
class QuickSortTailCall class QuickSortTailCall
class << self class << self
# ## Разбиение с опорными указателями ### ### Разбиение с опорными указателями ###
def partition(nums, left, right) def partition(nums, left, right)
# Использовать nums[left] как опорный элемент # Использовать nums[left] как опорный элемент
i = left i = left

View File

@@ -4,7 +4,7 @@ Created Time: 2024-05-03
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end =end
# ## Получить k-й разряд элемента num, где exp = 10^(k-1) ### ### Получить k-й разряд элемента num, где exp = 10^(k-1) ###
def digit(num, exp) def digit(num, exp)
# Передача exp вместо k позволяет избежать повторного выполнения дорогостоящих вычислений степени # Передача exp вместо k позволяет избежать повторного выполнения дорогостоящих вычислений степени
(num / exp) % 10 (num / exp) % 10
@@ -34,7 +34,7 @@ def counting_sort_digit(nums, exp)
(0...n).each { |i| nums[i] = res[i] } (0...n).each { |i| nums[i] = res[i] }
end end
# ## Поразрядная сортировка ### ### Поразрядная сортировка ###
def radix_sort(nums) def radix_sort(nums)
# Получить максимальный элемент массива, чтобы определить максимальное число разрядов # Получить максимальный элемент массива, чтобы определить максимальное число разрядов
m = nums.max m = nums.max

View File

@@ -4,7 +4,7 @@ Created Time: 2024-05-03
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end =end
# ## Сортировка выбором ### ### Сортировка выбором ###
def selection_sort(nums) def selection_sort(nums)
n = nums.length n = nums.length
# Внешний цикл: неотсортированный диапазон [i, n-1] # Внешний цикл: неотсортированный диапазон [i, n-1]

View File

@@ -4,29 +4,29 @@ Created Time: 2024-04-05
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end =end
# ## Двусторонняя очередь на основе кольцевого массива ### ### Двусторонняя очередь на основе кольцевого массива ###
class ArrayDeque class ArrayDeque
# ## Получение длины двусторонней очереди ### ### Получение длины двусторонней очереди ###
attr_reader :size attr_reader :size
# ## Конструктор ### ### Конструктор ###
def initialize(capacity) def initialize(capacity)
@nums = Array.new(capacity, 0) @nums = Array.new(capacity, 0)
@front = 0 @front = 0
@size = 0 @size = 0
end end
# ## Получить вместимость двусторонней очереди ### ### Получить вместимость двусторонней очереди ###
def capacity def capacity
@nums.length @nums.length
end end
# ## Проверка, пуста ли двусторонняя очередь ### ### Проверка, пуста ли двусторонняя очередь ###
def is_empty? def is_empty?
size.zero? size.zero?
end end
# ## Добавление в голову очереди ### ### Добавление в голову очереди ###
def push_first(num) def push_first(num)
if size == capacity if size == capacity
puts 'Двусторонняя очередь заполнена' puts 'Двусторонняя очередь заполнена'
@@ -41,7 +41,7 @@ class ArrayDeque
@size += 1 @size += 1
end end
# ## Добавление в хвост очереди ### ### Добавление в хвост очереди ###
def push_last(num) def push_last(num)
if size == capacity if size == capacity
puts 'Двусторонняя очередь заполнена' puts 'Двусторонняя очередь заполнена'
@@ -55,7 +55,7 @@ class ArrayDeque
@size += 1 @size += 1
end end
# ## Извлечение из головы очереди ### ### Извлечение из головы очереди ###
def pop_first def pop_first
num = peek_first num = peek_first
# Указатель головы сдвигается на одну позицию назад # Указатель головы сдвигается на одну позицию назад
@@ -64,21 +64,21 @@ class ArrayDeque
num num
end end
# ## Извлечение из хвоста очереди ### ### Извлечение из хвоста очереди ###
def pop_last def pop_last
num = peek_last num = peek_last
@size -= 1 @size -= 1
num num
end end
# ## Доступ к элементу в начале очереди ### ### Доступ к элементу в начале очереди ###
def peek_first def peek_first
raise IndexError, 'двусторонняя очередь пуста' if is_empty? raise IndexError, 'двусторонняя очередь пуста' if is_empty?
@nums[@front] @nums[@front]
end end
# ## Доступ к элементу в хвосте очереди ### ### Доступ к элементу в хвосте очереди ###
def peek_last def peek_last
raise IndexError, 'двусторонняя очередь пуста' if is_empty? raise IndexError, 'двусторонняя очередь пуста' if is_empty?
@@ -87,7 +87,7 @@ class ArrayDeque
@nums[last] @nums[last]
end end
# ## Вернуть массив для вывода ### ### Вернуть массив для вывода ###
def to_array def to_array
# Преобразовывать только элементы списка в пределах фактической длины # Преобразовывать только элементы списка в пределах фактической длины
res = [] res = []
@@ -99,7 +99,7 @@ class ArrayDeque
private private
# ## Вычислить индекс в кольцевом массиве ### ### Вычислить индекс в кольцевом массиве ###
def index(i) def index(i)
# С помощью операции взятия по модулю соединить начало и конец массива # С помощью операции взятия по модулю соединить начало и конец массива
# Когда i выходит за конец массива, он возвращается в начало # Когда i выходит за конец массива, он возвращается в начало

View File

@@ -4,29 +4,29 @@ Created Time: 2024-04-05
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end =end
# ## Очередь на основе кольцевого массива ### ### Очередь на основе кольцевого массива ###
class ArrayQueue class ArrayQueue
# ## Получение длины очереди ### ### Получение длины очереди ###
attr_reader :size attr_reader :size
# ## Конструктор ### ### Конструктор ###
def initialize(size) def initialize(size)
@nums = Array.new(size, 0) # Массив для хранения элементов очереди @nums = Array.new(size, 0) # Массив для хранения элементов очереди
@front = 0 # Указатель head, указывающий на первый элемент очереди @front = 0 # Указатель head, указывающий на первый элемент очереди
@size = 0 # Длина очереди @size = 0 # Длина очереди
end end
# ## Получить вместимость очереди ### ### Получить вместимость очереди ###
def capacity def capacity
@nums.length @nums.length
end end
# ## Проверка, пуста ли очередь ### ### Проверка, пуста ли очередь ###
def is_empty? def is_empty?
size.zero? size.zero?
end end
# ## Добавление в очередь ### ### Добавление в очередь ###
def push(num) def push(num)
raise IndexError, 'очередь заполнена' if size == capacity raise IndexError, 'очередь заполнена' if size == capacity
@@ -38,7 +38,7 @@ class ArrayQueue
@size += 1 @size += 1
end end
# ## Извлечение из очереди ### ### Извлечение из очереди ###
def pop def pop
num = peek num = peek
# Указатель head сдвигается на одну позицию назад; если он выходит за конец, то возвращается в начало массива # Указатель head сдвигается на одну позицию назад; если он выходит за конец, то возвращается в начало массива
@@ -47,14 +47,14 @@ class ArrayQueue
num num
end end
# ## Доступ к элементу в начале очереди ### ### Доступ к элементу в начале очереди ###
def peek def peek
raise IndexError, 'очередь пуста' if is_empty? raise IndexError, 'очередь пуста' if is_empty?
@nums[@front] @nums[@front]
end end
# ## Вернуть список для вывода ### ### Вернуть список для вывода ###
def to_array def to_array
res = Array.new(size, 0) res = Array.new(size, 0)
j = @front j = @front

View File

@@ -4,43 +4,43 @@ Created Time: 2024-04-06
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end =end
# ## Стек на основе массива ### ### Стек на основе массива ###
class ArrayStack class ArrayStack
# ## Конструктор ### ### Конструктор ###
def initialize def initialize
@stack = [] @stack = []
end end
# ## Получить длину стека ### ### Получить длину стека ###
def size def size
@stack.length @stack.length
end end
# ## Проверка, пуст ли стек ### ### Проверка, пуст ли стек ###
def is_empty? def is_empty?
@stack.empty? @stack.empty?
end end
# ## Помещение в стек ### ### Помещение в стек ###
def push(item) def push(item)
@stack << item @stack << item
end end
# ## Извлечение из стека ### ### Извлечение из стека ###
def pop def pop
raise IndexError, 'стек пуст' if is_empty? raise IndexError, 'стек пуст' if is_empty?
@stack.pop @stack.pop
end end
# ## Доступ к верхнему элементу стека ### ### Доступ к верхнему элементу стека ###
def peek def peek
raise IndexError, 'стек пуст' if is_empty? raise IndexError, 'стек пуст' if is_empty?
@stack.last @stack.last
end end
# ## Вернуть список для вывода ### ### Вернуть список для вывода ###
def to_array def to_array
@stack @stack
end end

View File

@@ -10,30 +10,30 @@ class ListNode
attr_accessor :next # Ссылка на узел-преемник attr_accessor :next # Ссылка на узел-преемник
attr_accessor :prev # Ссылка на узел-предшественник attr_accessor :prev # Ссылка на узел-предшественник
# ## Конструктор ### ### Конструктор ###
def initialize(val) def initialize(val)
@val = val @val = val
end end
end end
# ## Двусторонняя очередь на основе двусвязного списка ### ### Двусторонняя очередь на основе двусвязного списка ###
class LinkedListDeque class LinkedListDeque
# ## Получение длины двусторонней очереди ### ### Получение длины двусторонней очереди ###
attr_reader :size attr_reader :size
# ## Конструктор ### ### Конструктор ###
def initialize def initialize
@front = nil # Головной узел front @front = nil # Головной узел front
@rear = nil # Хвостовой узел rear @rear = nil # Хвостовой узел rear
@size = 0 # Длина двусторонней очереди @size = 0 # Длина двусторонней очереди
end end
# ## Проверка, пуста ли двусторонняя очередь ### ### Проверка, пуста ли двусторонняя очередь ###
def is_empty? def is_empty?
size.zero? size.zero?
end end
# ## Операция добавления в очередь ### ### Операция добавления в очередь ###
def push(num, is_front) def push(num, is_front)
node = ListNode.new(num) node = ListNode.new(num)
# Если связный список пуст, пусть front и rear оба указывают на node # Если связный список пуст, пусть front и rear оба указывают на node
@@ -55,17 +55,17 @@ class LinkedListDeque
@size += 1 # Обновить длину очереди @size += 1 # Обновить длину очереди
end end
# ## Добавление в голову очереди ### ### Добавление в голову очереди ###
def push_first(num) def push_first(num)
push(num, true) push(num, true)
end end
# ## Добавление в хвост очереди ### ### Добавление в хвост очереди ###
def push_last(num) def push_last(num)
push(num, false) push(num, false)
end end
# ## Операция извлечения из очереди ### ### Операция извлечения из очереди ###
def pop(is_front) def pop(is_front)
raise IndexError, 'двусторонняя очередь пуста' if is_empty? raise IndexError, 'двусторонняя очередь пуста' if is_empty?
@@ -95,31 +95,31 @@ class LinkedListDeque
val val
end end
# ## Извлечение из головы очереди ### ### Извлечение из головы очереди ###
def pop_first def pop_first
pop(true) pop(true)
end end
# ## Извлечение из головы очереди ### ### Извлечение из головы очереди ###
def pop_last def pop_last
pop(false) pop(false)
end end
# ## Доступ к элементу в начале очереди ### ### Доступ к элементу в начале очереди ###
def peek_first def peek_first
raise IndexError, 'двусторонняя очередь пуста' if is_empty? raise IndexError, 'двусторонняя очередь пуста' if is_empty?
@front.val @front.val
end end
# ## Доступ к элементу в хвосте очереди ### ### Доступ к элементу в хвосте очереди ###
def peek_last def peek_last
raise IndexError, 'двусторонняя очередь пуста' if is_empty? raise IndexError, 'двусторонняя очередь пуста' if is_empty?
@rear.val @rear.val
end end
# ## Вернуть массив для вывода ### ### Вернуть массив для вывода ###
def to_array def to_array
node = @front node = @front
res = Array.new(size, 0) res = Array.new(size, 0)

View File

@@ -6,24 +6,24 @@ Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
require_relative '../utils/list_node' require_relative '../utils/list_node'
# ## Очередь на основе связного списка ### ### Очередь на основе связного списка ###
class LinkedListQueue class LinkedListQueue
# ## Получение длины очереди ### ### Получение длины очереди ###
attr_reader :size attr_reader :size
# ## Конструктор ### ### Конструктор ###
def initialize def initialize
@front = nil # Головной узел front @front = nil # Головной узел front
@rear = nil # Хвостовой узел rear @rear = nil # Хвостовой узел rear
@size = 0 @size = 0
end end
# ## Проверка, пуста ли очередь ### ### Проверка, пуста ли очередь ###
def is_empty? def is_empty?
@front.nil? @front.nil?
end end
# ## Добавление в очередь ### ### Добавление в очередь ###
def push(num) def push(num)
# Добавить num после хвостового узла # Добавить num после хвостового узла
node = ListNode.new(num) node = ListNode.new(num)
@@ -41,7 +41,7 @@ class LinkedListQueue
@size += 1 @size += 1
end end
# ## Извлечение из очереди ### ### Извлечение из очереди ###
def pop def pop
num = peek num = peek
# Удалить головной узел # Удалить головной узел
@@ -50,14 +50,14 @@ class LinkedListQueue
num num
end end
# ## Доступ к элементу в начале очереди ### ### Доступ к элементу в начале очереди ###
def peek def peek
raise IndexError, 'очередь пуста' if is_empty? raise IndexError, 'очередь пуста' if is_empty?
@front.val @front.val
end end
# ## Преобразовать связный список в Array и вернуть ### ### Преобразовать связный список в Array и вернуть ###
def to_array def to_array
queue = [] queue = []
temp = @front temp = @front

View File

@@ -6,21 +6,21 @@ Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
require_relative '../utils/list_node' require_relative '../utils/list_node'
# ## Стек на основе связного списка ### ### Стек на основе связного списка ###
class LinkedListStack class LinkedListStack
attr_reader :size attr_reader :size
# ## Конструктор ### ### Конструктор ###
def initialize def initialize
@size = 0 @size = 0
end end
# ## Проверка, пуст ли стек ### ### Проверка, пуст ли стек ###
def is_empty? def is_empty?
@peek.nil? @peek.nil?
end end
# ## Помещение в стек ### ### Помещение в стек ###
def push(val) def push(val)
node = ListNode.new(val) node = ListNode.new(val)
node.next = @peek node.next = @peek
@@ -28,7 +28,7 @@ class LinkedListStack
@size += 1 @size += 1
end end
# ## Извлечение из стека ### ### Извлечение из стека ###
def pop def pop
num = peek num = peek
@peek = @peek.next @peek = @peek.next
@@ -36,14 +36,14 @@ class LinkedListStack
num num
end end
# ## Доступ к верхнему элементу стека ### ### Доступ к верхнему элементу стека ###
def peek def peek
raise IndexError, 'стек пуст' if is_empty? raise IndexError, 'стек пуст' if is_empty?
@peek.val @peek.val
end end
# ## Преобразовать связный список в Array и вернуть ### ### Преобразовать связный список в Array и вернуть ###
def to_array def to_array
arr = [] arr = []
node = @peek node = @peek

View File

@@ -7,19 +7,19 @@ Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
require_relative '../utils/tree_node' require_relative '../utils/tree_node'
require_relative '../utils/print_util' require_relative '../utils/print_util'
# ## Класс двоичного дерева в массивном представлении ### ### Класс двоичного дерева в массивном представлении ###
class ArrayBinaryTree class ArrayBinaryTree
# ## Конструктор ### ### Конструктор ###
def initialize(arr) def initialize(arr)
@tree = arr.to_a @tree = arr.to_a
end end
# ## Вместимость списка ### ### Вместимость списка ###
def size def size
@tree.length @tree.length
end end
# ## Получить значение узла с индексом i ### ### Получить значение узла с индексом i ###
def val(i) def val(i)
# Если индекс выходит за границы, вернуть nil, обозначающий пустую ячейку # Если индекс выходит за границы, вернуть nil, обозначающий пустую ячейку
return if i < 0 || i >= size return if i < 0 || i >= size
@@ -27,22 +27,22 @@ class ArrayBinaryTree
@tree[i] @tree[i]
end end
# ## Получить индекс левого дочернего узла узла с индексом i ### ### Получить индекс левого дочернего узла узла с индексом i ###
def left(i) def left(i)
2 * i + 1 2 * i + 1
end end
# ## Получить индекс правого дочернего узла узла с индексом i ### ### Получить индекс правого дочернего узла узла с индексом i ###
def right(i) def right(i)
2 * i + 2 2 * i + 2
end end
# ## Получить индекс родительского узла узла с индексом i ### ### Получить индекс родительского узла узла с индексом i ###
def parent(i) def parent(i)
(i - 1) / 2 (i - 1) / 2
end end
# ## Обход в ширину ### ### Обход в ширину ###
def level_order def level_order
@res = [] @res = []
@@ -54,7 +54,7 @@ class ArrayBinaryTree
@res @res
end end
# ## Обход в глубину ### ### Обход в глубину ###
def dfs(i, order) def dfs(i, order)
return if val(i).nil? return if val(i).nil?
# Предварительный обход # Предварительный обход
@@ -67,21 +67,21 @@ class ArrayBinaryTree
@res << val(i) if order == :post @res << val(i) if order == :post
end end
# ## Предварительный обход ### ### Предварительный обход ###
def pre_order def pre_order
@res = [] @res = []
dfs(0, :pre) dfs(0, :pre)
@res @res
end end
# ## Симметричный обход ### ### Симметричный обход ###
def in_order def in_order
@res = [] @res = []
dfs(0, :in) dfs(0, :in)
@res @res
end end
# ## Обратный обход ### ### Обратный обход ###
def post_order def post_order
@res = [] @res = []
dfs(0, :post) dfs(0, :post)

View File

@@ -7,19 +7,19 @@ Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
require_relative '../utils/tree_node' require_relative '../utils/tree_node'
require_relative '../utils/print_util' require_relative '../utils/print_util'
# ## AVL-дерево ### ### AVL-дерево ###
class AVLTree class AVLTree
# ## Конструктор ### ### Конструктор ###
def initialize def initialize
@root = nil @root = nil
end end
# ## Получение корневого узла двоичного дерева ### ### Получение корневого узла двоичного дерева ###
def get_root def get_root
@root @root
end end
# ## Получить высоту узла ### ### Получить высоту узла ###
def height(node) def height(node)
# Высота пустого узла равна -1, высота листового узла равна 0 # Высота пустого узла равна -1, высота листового узла равна 0
return node.height unless node.nil? return node.height unless node.nil?
@@ -27,13 +27,13 @@ class AVLTree
-1 -1
end end
# ## Обновить высоту узла ### ### Обновить высоту узла ###
def update_height(node) def update_height(node)
# Высота узла равна высоте более высокого поддерева + 1 # Высота узла равна высоте более высокого поддерева + 1
node.height = [height(node.left), height(node.right)].max + 1 node.height = [height(node.left), height(node.right)].max + 1
end end
# ## Получить коэффициент баланса ### ### Получить коэффициент баланса ###
def balance_factor(node) def balance_factor(node)
# Коэффициент баланса пустого узла равен 0 # Коэффициент баланса пустого узла равен 0
return 0 if node.nil? return 0 if node.nil?
@@ -42,7 +42,7 @@ class AVLTree
height(node.left) - height(node.right) height(node.left) - height(node.right)
end end
# ## Операция правого вращения ### ### Операция правого вращения ###
def right_rotate(node) def right_rotate(node)
child = node.left child = node.left
grand_child = child.right grand_child = child.right
@@ -56,7 +56,7 @@ class AVLTree
child child
end end
# ## Операция левого вращения ### ### Операция левого вращения ###
def left_rotate(node) def left_rotate(node)
child = node.right child = node.right
grand_child = child.left grand_child = child.left
@@ -70,7 +70,7 @@ class AVLTree
child child
end end
# ## Выполнить вращение, чтобы снова сбалансировать поддерево ### ### Выполнить вращение, чтобы снова сбалансировать поддерево ###
def rotate(node) def rotate(node)
# Получить коэффициент баланса узла node # Получить коэффициент баланса узла node
balance_factor = balance_factor(node) balance_factor = balance_factor(node)
@@ -99,7 +99,7 @@ class AVLTree
node node
end end
# ## Вставка узла ### ### Вставка узла ###
def insert(val) def insert(val)
@root = insert_helper(@root, val) @root = insert_helper(@root, val)
end end
@@ -122,7 +122,7 @@ class AVLTree
rotate(node) rotate(node)
end end
# ## Удаление узла ### ### Удаление узла ###
def remove(val) def remove(val)
@root = remove_helper(@root, val) @root = remove_helper(@root, val)
end end
@@ -158,7 +158,7 @@ class AVLTree
rotate(node) rotate(node)
end end
# ## Поиск узла ### ### Поиск узла ###
def search(val) def search(val)
cur = @root cur = @root
# Искать в цикле и выйти после прохода за листовой узел # Искать в цикле и выйти после прохода за листовой узел

View File

@@ -7,20 +7,20 @@ Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
require_relative '../utils/tree_node' require_relative '../utils/tree_node'
require_relative '../utils/print_util' require_relative '../utils/print_util'
# ## Двоичное дерево поиска ### ### Двоичное дерево поиска ###
class BinarySearchTree class BinarySearchTree
# ## Конструктор ### ### Конструктор ###
def initialize def initialize
# Инициализировать пустое дерево # Инициализировать пустое дерево
@root = nil @root = nil
end end
# ## Получение корневого узла двоичного дерева ### ### Получение корневого узла двоичного дерева ###
def get_root def get_root
@root @root
end end
# ## Поиск узла ### ### Поиск узла ###
def search(num) def search(num)
cur = @root cur = @root
@@ -41,7 +41,7 @@ class BinarySearchTree
cur cur
end end
# ## Вставка узла ### ### Вставка узла ###
def insert(num) def insert(num)
# Если дерево пусто, инициализировать корневой узел # Если дерево пусто, инициализировать корневой узел
if @root.nil? if @root.nil?
@@ -74,7 +74,7 @@ class BinarySearchTree
end end
end end
# ## Удаление узла ### ### Удаление узла ###
def remove(num) def remove(num)
# Если дерево пусто, сразу вернуть # Если дерево пусто, сразу вернуть
return if @root.nil? return if @root.nil?

View File

@@ -7,7 +7,7 @@ Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
require_relative '../utils/tree_node' require_relative '../utils/tree_node'
require_relative '../utils/print_util' require_relative '../utils/print_util'
# ## Обход в ширину ### ### Обход в ширину ###
def level_order(root) def level_order(root)
# Инициализировать очередь и добавить корневой узел # Инициализировать очередь и добавить корневой узел
queue = [root] queue = [root]

View File

@@ -7,7 +7,7 @@ Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
require_relative '../utils/tree_node' require_relative '../utils/tree_node'
require_relative '../utils/print_util' require_relative '../utils/print_util'
# ## Предварительный обход ### ### Предварительный обход ###
def pre_order(root) def pre_order(root)
return if root.nil? return if root.nil?
@@ -17,7 +17,7 @@ def pre_order(root)
pre_order(root.right) pre_order(root.right)
end end
# ## Симметричный обход ### ### Симметричный обход ###
def in_order(root) def in_order(root)
return if root.nil? return if root.nil?
@@ -27,7 +27,7 @@ def in_order(root)
in_order(root.right) in_order(root.right)
end end
# ## Обратный обход ### ### Обратный обход ###
def post_order(root) def post_order(root)
return if root.nil? return if root.nil?

View File

@@ -4,7 +4,7 @@ Created Time: 2024-03-18
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end =end
# ## Класс узла связного списка ### ### Класс узла связного списка ###
class ListNode class ListNode
attr_accessor :val # Значение узла attr_accessor :val # Значение узла
attr_accessor :next # Ссылка на следующий узел attr_accessor :next # Ссылка на следующий узел
@@ -15,7 +15,7 @@ class ListNode
end end
end end
# ## Десериализация списка в связный список ### ### Десериализация списка в связный список ###
def arr_to_linked_list(arr) def arr_to_linked_list(arr)
head = current = ListNode.new(arr[0]) head = current = ListNode.new(arr[0])
@@ -27,7 +27,7 @@ def arr_to_linked_list(arr)
head head
end end
# ## Сериализация связного списка в список ### ### Сериализация связного списка в список ###
def linked_list_to_arr(head) def linked_list_to_arr(head)
arr = [] arr = []

View File

@@ -6,14 +6,14 @@ Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
require_relative "./tree_node" require_relative "./tree_node"
# ## Вывести матрицу ### ### Вывести матрицу ###
def print_matrix(mat) def print_matrix(mat)
s = [] s = []
mat.each { |arr| s << " #{arr.to_s}" } mat.each { |arr| s << " #{arr.to_s}" }
puts "[\n#{s.join(",\n")}\n]" puts "[\n#{s.join(",\n")}\n]"
end end
# ## Вывести связный список ### ### Вывести связный список ###
def print_linked_list(head) def print_linked_list(head)
list = [] list = []
while head while head
@@ -39,8 +39,8 @@ def show_trunk(p)
print p.str print p.str
end end
# ## Вывести двоичное дерево ### ### Вывести двоичное дерево ###
# Этот вывод дерева заимствован из TECHIE DELIGHT # This tree printer is borrowed from TECHIE DELIGHT
# https://www.techiedelight.com/c-program-print-binary-tree/ # https://www.techiedelight.com/c-program-print-binary-tree/
def print_tree(root, prev=nil, is_right=false) def print_tree(root, prev=nil, is_right=false)
return if root.nil? return if root.nil?
@@ -66,12 +66,12 @@ def print_tree(root, prev=nil, is_right=false)
print_tree(root.left, trunk, false) print_tree(root.left, trunk, false)
end end
# ## Вывести хеш-таблицу ### ### Вывести хеш-таблицу ###
def print_hash_map(hmap) def print_hash_map(hmap)
hmap.entries.each { |key, value| puts "#{key} -> #{value}" } hmap.entries.each { |key, value| puts "#{key} -> #{value}" }
end end
# ## Вывести кучу ### ### Вывести кучу ###
def print_heap(heap) def print_heap(heap)
puts "Массивное представление кучи:#{heap}" puts "Массивное представление кучи:#{heap}"
puts "Древовидное представление кучи:" puts "Древовидное представление кучи:"

View File

@@ -4,7 +4,7 @@ Created Time: 2024-03-30
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end =end
# ## Класс узла двоичного дерева ### ### Класс узла двоичного дерева ###
class TreeNode class TreeNode
attr_accessor :val # Значение узла attr_accessor :val # Значение узла
attr_accessor :height # Высота узла attr_accessor :height # Высота узла
@@ -17,7 +17,7 @@ class TreeNode
end end
end end
# ## Десериализация списка в двоичное дерево: рекурсия ### ### Десериализация списка в двоичное дерево: рекурсия ###
def arr_to_tree_dfs(arr, i) def arr_to_tree_dfs(arr, i)
# Если индекс выходит за длину массива или соответствующий элемент равен nil, вернуть nil # Если индекс выходит за длину массива или соответствующий элемент равен nil, вернуть nil
return if i < 0 || i >= arr.length || arr[i].nil? return if i < 0 || i >= arr.length || arr[i].nil?
@@ -29,12 +29,12 @@ def arr_to_tree_dfs(arr, i)
root root
end end
# ## Десериализация списка в двоичное дерево ### ### Десериализация списка в двоичное дерево ###
def arr_to_tree(arr) def arr_to_tree(arr)
arr_to_tree_dfs(arr, 0) arr_to_tree_dfs(arr, 0)
end end
# ## Сериализация двоичного дерева в список: рекурсия ### ### Сериализация двоичного дерева в список: рекурсия ###
def tree_to_arr_dfs(root, i, res) def tree_to_arr_dfs(root, i, res)
return if root.nil? return if root.nil?
@@ -45,7 +45,7 @@ def tree_to_arr_dfs(root, i, res)
tree_to_arr_dfs(root.right, 2 * i + 2, res) tree_to_arr_dfs(root.right, 2 * i + 2, res)
end end
# ## Сериализация двоичного дерева в список ### ### Сериализация двоичного дерева в список ###
def tree_to_arr(root) def tree_to_arr(root)
res = [] res = []
tree_to_arr_dfs(root, 0, res) tree_to_arr_dfs(root, 0, res)

View File

@@ -4,7 +4,7 @@ Created Time: 2024-04-25
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end =end
# ## Класс вершины ### ### Класс вершины ###
class Vertex class Vertex
attr_accessor :val attr_accessor :val
@@ -13,12 +13,12 @@ class Vertex
end end
end end
# ## На вход подается список значений vals, на выходе возвращается список вершин vets ### ### На вход подается список значений vals, на выходе возвращается список вершин vets ###
def vals_to_vets(vals) def vals_to_vets(vals)
Array.new(vals.length) { |i| Vertex.new(vals[i]) } Array.new(vals.length) { |i| Vertex.new(vals[i]) }
end end
# ## На вход подается список вершин vets, на выходе возвращается список значений vals ### ### На вход подается список вершин vets, на выходе возвращается список значений vals ###
def vets_to_vals(vets) def vets_to_vals(vets)
Array.new(vets.length) { |i| vets[i].val } Array.new(vets.length) { |i| vets[i].val }
end end

View File

@@ -3,135 +3,135 @@
В таблице ниже перечислены важные термины, встречающиеся в книге. Обратите внимание на следующие моменты. В таблице ниже перечислены важные термины, встречающиеся в книге. Обратите внимание на следующие моменты.
- Рекомендуем запомнить английские названия терминов, чтобы легче читать англоязычную литературу. - Рекомендуем запомнить английские названия терминов, чтобы легче читать англоязычную литературу.
- В русской версии третий столбец дублирует основной перевод, чтобы сохранить единый формат таблицы. - В русской версии приводится единый рекомендуемый перевод каждого термина.
<p align="center"> Таблица <id> &nbsp; Важные термины по структурам данных и алгоритмам </p> <p align="center"> Таблица <id> &nbsp; Важные термины по структурам данных и алгоритмам </p>
| English | Русский | Русский | | English | Русский |
| ------------------------------ | ------------------------------ | ------------------------------ | | ------------------------------ | ------------------------------ |
| algorithm | алгоритм | алгоритм | | algorithm | алгоритм |
| data structure | структура данных | структура данных | | data structure | структура данных |
| code | код | код | | code | код |
| file | файл | файл | | file | файл |
| function | функция | функция | | function | функция |
| method | метод | метод | | method | метод |
| variable | переменная | переменная | | variable | переменная |
| asymptotic complexity analysis | асимптотический анализ сложности | асимптотический анализ сложности | | asymptotic complexity analysis | асимптотический анализ сложности |
| time complexity | временная сложность | временная сложность | | time complexity | временная сложность |
| space complexity | пространственная сложность | пространственная сложность | | space complexity | пространственная сложность |
| loop | цикл | цикл | | loop | цикл |
| iteration | итерация | итерация | | iteration | итерация |
| recursion | рекурсия | рекурсия | | recursion | рекурсия |
| tail recursion | хвостовая рекурсия | хвостовая рекурсия | | tail recursion | хвостовая рекурсия |
| recursion tree | дерево рекурсии | дерево рекурсии | | recursion tree | дерево рекурсии |
| big-$O$ notation | нотация big-$O$ | нотация big-$O$ | | big-$O$ notation | нотация big-$O$ |
| asymptotic upper bound | асимптотическая верхняя граница | асимптотическая верхняя граница | | asymptotic upper bound | асимптотическая верхняя граница |
| sign-magnitude | прямой код | прямой код | | sign-magnitude | прямой код |
| 1s complement | обратный код | обратный код | | 1s complement | обратный код |
| 2s complement | дополнительный код | дополнительный код | | 2s complement | дополнительный код |
| array | массив | массив | | array | массив |
| index | индекс | индекс | | index | индекс |
| linked list | связный список | связный список | | linked list | связный список |
| linked list node, list node | узел связного списка | узел связного списка | | linked list node, list node | узел связного списка |
| head node | головной узел | головной узел | | head node | головной узел |
| tail node | хвостовой узел | хвостовой узел | | tail node | хвостовой узел |
| list | список | список | | list | список |
| dynamic array | динамический массив | динамический массив | | dynamic array | динамический массив |
| hard disk | жесткий диск | жесткий диск | | hard disk | жесткий диск |
| random-access memory (RAM) | оперативная память | оперативная память | | random-access memory (RAM) | оперативная память |
| cache memory | кеш-память | кеш-память | | cache memory | кеш-память |
| cache miss | промах кеша | промах кеша | | cache miss | промах кеша |
| cache hit rate | коэффициент попадания в кеш | коэффициент попадания в кеш | | cache hit rate | коэффициент попадания в кеш |
| stack | стек | стек | | stack | стек |
| top of the stack | вершина стека | вершина стека | | top of the stack | вершина стека |
| bottom of the stack | основание стека | основание стека | | bottom of the stack | основание стека |
| queue | очередь | очередь | | queue | очередь |
| double-ended queue | двусторонняя очередь | двусторонняя очередь | | double-ended queue | двусторонняя очередь |
| front of the queue | голова очереди | голова очереди | | front of the queue | голова очереди |
| rear of the queue | хвост очереди | хвост очереди | | rear of the queue | хвост очереди |
| hash table | хеш-таблица | хеш-таблица | | hash table | хеш-таблица |
| hash set | хеш-набор | хеш-набор | | hash set | хеш-набор |
| bucket | корзина | корзина | | bucket | корзина |
| hash function | хеш-функция | хеш-функция | | hash function | хеш-функция |
| hash collision | хеш-коллизия | хеш-коллизия | | hash collision | хеш-коллизия |
| load factor | коэффициент заполнения | коэффициент заполнения | | load factor | коэффициент заполнения |
| separate chaining | цепная адресация | цепная адресация | | separate chaining | цепная адресация |
| open addressing | открытая адресация | открытая адресация | | open addressing | открытая адресация |
| linear probing | линейное зондирование | линейное зондирование | | linear probing | линейное зондирование |
| lazy deletion | ленивое удаление | ленивое удаление | | lazy deletion | ленивое удаление |
| binary tree | двоичное дерево | двоичное дерево | | binary tree | двоичное дерево |
| tree node | узел дерева | узел дерева | | tree node | узел дерева |
| left-child node | левый дочерний узел | левый дочерний узел | | left-child node | левый дочерний узел |
| right-child node | правый дочерний узел | правый дочерний узел | | right-child node | правый дочерний узел |
| parent node | родительский узел | родительский узел | | parent node | родительский узел |
| left subtree | левое поддерево | левое поддерево | | left subtree | левое поддерево |
| right subtree | правое поддерево | правое поддерево | | right subtree | правое поддерево |
| root node | корневой узел | корневой узел | | root node | корневой узел |
| leaf node | листовой узел | листовой узел | | leaf node | листовой узел |
| edge | ребро | ребро | | edge | ребро |
| level | уровень | уровень | | level | уровень |
| degree | степень | степень | | degree | степень |
| height | высота | высота | | height | высота |
| depth | глубина | глубина | | depth | глубина |
| perfect binary tree | идеальное двоичное дерево | идеальное двоичное дерево | | perfect binary tree | идеальное двоичное дерево |
| complete binary tree | совершенное двоичное дерево | совершенное двоичное дерево | | complete binary tree | совершенное двоичное дерево |
| full binary tree | полное двоичное дерево | полное двоичное дерево | | full binary tree | полное двоичное дерево |
| balanced binary tree | сбалансированное двоичное дерево | сбалансированное двоичное дерево | | balanced binary tree | сбалансированное двоичное дерево |
| binary search tree | двоичное дерево поиска | двоичное дерево поиска | | binary search tree | двоичное дерево поиска |
| AVL tree | АВЛ-дерево | АВЛ-дерево | | AVL tree | АВЛ-дерево |
| red-black tree | красно-черное дерево | красно-черное дерево | | red-black tree | красно-черное дерево |
| level-order traversal | обход по уровням | обход по уровням | | level-order traversal | обход по уровням |
| breadth-first traversal | обход в ширину | обход в ширину | | breadth-first traversal | обход в ширину |
| depth-first traversal | обход в глубину | обход в глубину | | depth-first traversal | обход в глубину |
| binary search tree | двоичное дерево поиска | двоичное дерево поиска | | binary search tree | двоичное дерево поиска |
| balanced binary search tree | сбалансированное двоичное дерево поиска | сбалансированное двоичное дерево поиска | | balanced binary search tree | сбалансированное двоичное дерево поиска |
| balance factor | фактор баланса | фактор баланса | | balance factor | фактор баланса |
| heap | куча | куча | | heap | куча |
| max heap | максимальная куча | максимальная куча | | max heap | максимальная куча |
| min heap | минимальная куча | минимальная куча | | min heap | минимальная куча |
| priority queue | приоритетная очередь | приоритетная очередь | | priority queue | приоритетная очередь |
| heapify | упорядочивание кучи | упорядочивание кучи | | heapify | упорядочивание кучи |
| top-$k$ problem | поиск $k$ наибольших элементов | поиск $k$ наибольших элементов | | top-$k$ problem | поиск $k$ наибольших элементов |
| graph | граф | граф | | graph | граф |
| vertex | вершина | вершина | | vertex | вершина |
| undirected graph | неориентированный граф | неориентированный граф | | undirected graph | неориентированный граф |
| directed graph | ориентированный граф | ориентированный граф | | directed graph | ориентированный граф |
| connected graph | связный граф | связный граф | | connected graph | связный граф |
| disconnected graph | несвязный граф | несвязный граф | | disconnected graph | несвязный граф |
| weighted graph | взвешенный граф | взвешенный граф | | weighted graph | взвешенный граф |
| adjacency | смежность | смежность | | adjacency | смежность |
| path | путь | путь | | path | путь |
| in-degree | входящая степень | входящая степень | | in-degree | входящая степень |
| out-degree | исходящая степень | исходящая степень | | out-degree | исходящая степень |
| adjacency matrix | матрица смежности | матрица смежности | | adjacency matrix | матрица смежности |
| adjacency list | список смежности | список смежности | | adjacency list | список смежности |
| breadth-first search | поиск в ширину | поиск в ширину | | breadth-first search | поиск в ширину |
| depth-first search | поиск в глубину | поиск в глубину | | depth-first search | поиск в глубину |
| binary search | двоичный поиск | двоичный поиск | | binary search | двоичный поиск |
| searching algorithm | алгоритм поиска | алгоритм поиска | | searching algorithm | алгоритм поиска |
| sorting algorithm | алгоритм сортировки | алгоритм сортировки | | sorting algorithm | алгоритм сортировки |
| selection sort | сортировка выбором | сортировка выбором | | selection sort | сортировка выбором |
| bubble sort | сортировка пузырьком | сортировка пузырьком | | bubble sort | сортировка пузырьком |
| insertion sort | сортировка вставкой | сортировка вставкой | | insertion sort | сортировка вставкой |
| quick sort | быстрая сортировка | быстрая сортировка | | quick sort | быстрая сортировка |
| merge sort | сортировка слиянием | сортировка слиянием | | merge sort | сортировка слиянием |
| heap sort | пирамидальная сортировка | пирамидальная сортировка | | heap sort | пирамидальная сортировка |
| bucket sort | блочная сортировка | блочная сортировка | | bucket sort | блочная сортировка |
| counting sort | сортировка подсчетом | сортировка подсчетом | | counting sort | сортировка подсчетом |
| radix sort | поразрядная сортировка | поразрядная сортировка | | radix sort | поразрядная сортировка |
| divide and conquer | разделяй и властвуй | разделяй и властвуй | | divide and conquer | разделяй и властвуй |
| hanota problem | задача о Ханойской башне | задача о Ханойской башне | | hanota problem | задача о Ханойской башне |
| backtracking algorithm | алгоритм поиска с возвратом | алгоритм поиска с возвратом | | backtracking algorithm | алгоритм поиска с возвратом |
| constraint | ограничение | ограничение | | constraint | ограничение |
| solution | решение | решение | | solution | решение |
| state | состояние | состояние | | state | состояние |
| pruning | отсечение | отсечение | | pruning | отсечение |
| permutations problem | задача о перестановках | задача о перестановках | | permutations problem | задача о перестановках |
| subset-sum problem | задача о сумме подмножеств | задача о сумме подмножеств | | subset-sum problem | задача о сумме подмножеств |
| $n$-queens problem | задача о $n$ ферзях | задача о $n$ ферзях | | $n$-queens problem | задача о $n$ ферзях |
| dynamic programming | динамическое программирование | динамическое программирование | | dynamic programming | динамическое программирование |
| initial state | начальное состояние | начальное состояние | | initial state | начальное состояние |
| state-transition equation | уравнение перехода состояния | уравнение перехода состояния | | state-transition equation | уравнение перехода состояния |
| knapsack problem | задача о рюкзаке | задача о рюкзаке | | knapsack problem | задача о рюкзаке |
| edit distance problem | задача о расстоянии редактирования | задача о расстоянии редактирования | | edit distance problem | задача о расстоянии редактирования |
| greedy algorithm | жадный алгоритм | жадный алгоритм | | greedy algorithm | жадный алгоритм |