Алгоритм системного решения проблем
Допустим, упал сайт. Или у кого-то отображается не тот номер телефона в подменах. Или в рекламной кампании обнаружены лишние ключевые фразы. Реакция по умолчанию: исправить и забыть. Такая реакция приводит к плохим последствиям: сложность проекта растёт, на починку уходит всё больше времени, а на настоящую работу — всё меньше.
Я для себя пришёл к такому алгоритму:
1. Обнаружена проблема
Сработал мониторинг. Или клиент прислал. Или сами заметили.
2. Подтвердить получение проблемы и срок реакции
Записать в тикет-систему / баг-трекер / докс. Уведомить менеджера / команду / клиента. «Принял, разбираюсь прямо сейчас». «Принял, посмотрю после задачи Х через час».
Если не уведомить, остальные будут нервничать в неизвестности. Не будет ощущения, что вы контролируете ситуацию. Что за вами не надо перепроверять. Что вам можно доверить что-либо важное.
3. Оценить критичность и составить план действий
Критичность определяется не паникой, а возможными последствиями в перспективе. Нужно представить и прочувствовать все последствия, сравнить с другими задачами и принять решение. Некоторые проблемы нужно решать прямо сейчас. Некоторые можно не решать.
Обычно получается так, что проблемы вытесняют задачи по развитию и системным решениям. Это не правильно. Если хорошо прочувствовать важность проблем и важность системных решений, то найдётся баланс.
4. Убедиться, что проблема действительно есть
Чтобы решить проблему, надо сначала её воспроизвести. Иногда это сложно. Надо либо воспроизвести, либо доказать, что её нет. «У меня не воспроизводится» — не ответ.
Снять проблему может только тот, кто о ней сообщил. Пока не снял, считаем проблему актуальной.
Иногда проблема только кажется проблемой, а на самом деле так и задумано. Тут помогает документация и память участников команды.
5. Подтвердить, что проблема есть, и сказать, когда исправите
Исправить можно сразу, через час, день, неделю или никогда. Зависит от критичности проблемы и ваших процессов.
Но информировать обязательно — для прозрачности, ощущения контроля и доверия.
6. Исправить
Исправить.
7. Проинформировать
Проинформировать, что исправили и рассказать, что собираемся делать дальше.
В этот момент менеджер и клиент считают, что главное уже сделано и ждут новостей по следующей Очень Важной Проблеме. На самом деле, самое важное ещё впереди. Если работу по алгоритму не довести до конца, то ошибки будут только накапливаться. Это в интересах менеджера и клиента не давать закрыть просто исправленную ошибку.
8. Сделать контрольную проверку
Проверить, что ошибка действительно исправлена. Обязательно сделать это другим способом. Желательно на следующий день со свежим взглядом. Например, сайт посмотреть в других браузерах и в мониторинге. Рекламу посмотреть не в интерфейсе, а в поиске и в статистике.
Вы не поверите, как часто контрольные проверки на следущий день обнаруживают недоисправленные ошибки.
9. Проинформировать
Мало кто делает контрольные проверки. У всех Нет Времени. Сделать и расказать — +1 в карму.
10. Что могло сломаться рядом? Что могли сломать, пока чинили?
Починили вёрстку в одном браузере? А в других? А на мобилках? А в версии для печати?
Изменили работу калькулятора на лендинге? А на основном сайте? А в других регионах? А события не поломали?
Обнаружили лишнее ключевое слово в одной РК? А есть в других? А в SEO? А в списке услуг на сайте?
Вообще-то, это надо делать сразу, но неплохо проверять ещё раз после.
Кстати, такое внимание к деталям и умение смотреть по сторонам — один из важных критериев проверки людей на стажировке.
11. Проинформировать
Ну вы поняли.
12. Посчитать цену ошибки
Мой любимый пункт. Почему-то считать очень не хочется. Или хочется посчитать по нижней границе. Но сделать это надо обязательно и не занижать.
Во-первых, команда часто не представляет, сколько стоят ошибки. Конкретное число в рублях отрезвляет и реально влияет на действия. Поводом к написанию этого поста стала серия очень дорогих ошибок. Это цена обучения. Если не посчитать, обучение будет менее эффективным.
Во-вторых, клиенты без точных данных рисуют в голове огромные цифры. А это далеко не всегда соответствует действительности.
Внимание: если в расчётах найдётся ошибка или процесс расчёта будет непонятен, то восстановить доверие будет сложно. Повышенная Бдительность.
13. Проинформировать
Вот здесь больно, да.
14. Найти системное решение
Надо сделать так, чтобы ошибка никогда не повторялась. Тут появляются мониторинги, чек-листы, регламенты и другие бюрократические штуки. Часто их не делают, потому считают любую бюрократию злом. Бюрократия бывает проблемой, но чаще проблема в отсутствии базовых процессов и чек-листов.
Кстати, «человек ошибся» — это не разовая ошибка. Люди ошибаются всегда, поэтому людей считаем системной ошибкой.
Ещё бывают редкие ошибки и дешёвые ошибки. Их может быть дешевле не лечить и честно об этом сказать. Например, глючащий несколько дней сервис онлайн-консультанта снизит выручку на 40 т.р.. Цена смены сервиса с переобучением людей и перестройкой аналитики — ~400 т.р. и ещё не известно как на конверсию повлияет. Решение Всё Поменять здесь было бы поспешным.
15. Проинформировать
Если не спрашивают, всё равно рассказать. Системные решения — это же самое важное.
16. Сделать отчёт для себя / команды / клиента в будущем
Отчёт идёт прямо по этому формату. По этим отчётам потом хорошо искать причины похожих проблем. И учить новеньких.
17. Что осталось сделать?
Закрывать тикет можно только когда ответ на этот вопрос пуст.
Как быть уверенным, что сделано действительно всё? Доверять внутреннему чутью. Чутье — это накопленный опыт и боль.
Ещё раз алгоритм списком (можете скопировать к себе)
Резюме
По этому алгоритму можно разбираться с чем угодно. Первым на ум приходят сайты и разработка, но оно подходит и для рекламы и для других процессов, и для управление проектами, компаниями, людьми. Даже с неудачной поездкой на велосипеде можно так разбираться.
В тривиальных случаях прохожу по алгоритму в уме. В сложных — открываю докс, копирую алгоритм и иду по пунктам.
РБК PRO: готовый алгоритм для решения проблем любой сложности
Одна из самых востребованных компетенций топ-менеджера — «комплексное решение сложных проблем». Я дам алгоритм, который поможет вам найти оптимальный способ решения проблемы, не хватаясь за первый пришедший в голову.
Некоторые исследователи отделяют термин «комплексное решение проблем» (complex problem solving) от другого — «принятие решений» (decision making), подразумевая, что между ними есть некая смысловая разница. Безусловно, некоторые механизмы обеих компетенций отличаются, однако фундамент у них общий. Поэтому я умышленно отождествляю «решение проблем» и «принятие решений», пользуясь нехитрым принципом: «Правильные решения устраняют проблемы». Что же такое проблемы? И почему так важно правильно с ними работать?
Под проблемой я понимаю некую трудность, которая не дает получить желаемое. Это может быть отсутствие готового решения, неудовлетворительное состояние текущих дел, непонимание достижения своей цели. Проблемы — часть нашей повседневной жизни. Препятствия окружают нас повсюду. Но есть хорошая новость: безвыходных ситуаций не бывает. Всегда существует как минимум три стратегии:
- решить проблему;
- изменить свое отношение к проблеме;
- проигнорировать проблему.
Я очень люблю фразу: «Если не можешь изменить ситуацию, измени свое отношение к ней». Она идеально описывает, как надо поступить, если нам не под силу решить проблему. Некоторые проблемы и вовсе не имеют решения. Поэтому их мы просто игнорируем, ведь жизнь одна, а время ограничено. Но понятие problem solving все же подразумевает поиск наилучшего решения проблемы.
Предлагаю алгоритм решения проблем, состоящий из пяти логичных шагов.
Шаг No 1. Установление проблемы
Четко и грамотно сформулируйте проблему или задачу. Поставьте перед собой цель. Звучит банально, но в реальной жизни этот этап часто игнорируется. «Зачем тратить время на какую-то формулировку проблемы, когда эту проблему надо решать?» — рассуждают многие. И зря. Зачастую мы решаем непонятно что. Недаром говорят: «Четко сформулированная проблема уже наполовину решена».
Поэтому чем конкретнее вы сформулируете проблему, тем легче будет найти ее решение. Членораздельно ответьте себе на вопрос: «В чем состоит сама проблема?» Может быть, ее вовсе и нет. А может быть, все интерпретируют и трактуют ее по-разному. Невозможно решить все проблемы скопом и за один раз. Поэтому в теории решения проблем есть ключевое правило: «Решайте проблемы по мере их поступления». С другой стороны, помните, что нет изолированных или автономных проблем. Все они взаимосвязаны и зачастую имеют одни и те же причины.
Шаг 2 — Анализ ситуации
Соберите всю информацию о текущей ситуации. Проанализируйте свою проблему. Разложите ее на составные части.
- Что предшествовало возникшей проблеме?
- Из-за чего она произошла?
- Это повторяющаяся проблема?
- Кто за нее ответственен?
- Каковы причины сложившейся ситуации?
- Из-за чего она возникла?
- Как эту проблему решали раньше?
- Насколько она действительно приоритетна для вас?
- Требует ли мгновенного решения?
В большинстве случаев именно неизвестная информация является ключевой. И пока вы ее не выявите, нельзя переходить к поиску путей решения. Этот принцип можно сформулировать так: «Более важно не то, что мы знаем о проблеме, а то, чего мы о ней не знаем».
В бизнесе я часто вижу, как люди решают не те проблемы, которые стоило бы решать, упускают из вида горящие и принципиально важные проблемы, распыляя свое внимание на мелочи. Поэтому я рекомендую использовать классический прием, которые называется матрица Эйзенхауэра. Он очень популярен в тайм-менеджменте, но его легко можно использовать для приоритизации проблем, а не дел. Матрица представляет собой четыре квадранта, в основании которых лежат две оси:
- ось важности
- ось срочности
В каждом из квадрантов находятся проблемы:
- важные и срочные
- важные и не срочные
- не важные и срочные
- не важные и не срочные
Несложно догадаться, что первым делом нужно решать проблемы, попавшие в первый квадрант. Потом — во второй и, наконец, в третий. А вот от «неважных и несрочных» лучше вообще избавиться, ибо они не стоят времени и усилий.
Шаг 3 — Разработка вариантов действий
Если вы поняли, что проблема приоритетна и требует незамедлительного решения, переходите к разработке вариантов действий. Я недаром пишу «вариантов», а не «варианта». Даже если решение проблемы лежит на поверхности, необходимо продумать несколько возможных альтернатив. Нередко очевидные решения таят в себе опасность. А вдруг не самое простое решение может сэкономить время, ресурсы и нервы? Моя практика подсказывает, что стоит выбирать не самые простые, а самые рациональные и разумные решения. Запомните: «Срочных идеальных решений не существует!».
Сгенерируйте как можно больше вариантов. Ройте так глубоко, насколько это возможно. Посмотрите на проблему максимально широко и незашоренным взглядом: «Может быть, стоит взглянуть на ситуацию с другой точки зрения?». Решая многие проблемы «на автомате», мы становимся заложниками многочисленных когнитивных искажений и наступаем на одни и те же грабли.
Шаг 4 — Выбор варианта действий
Тщательно проанализируйте каждый из вариантов действий, выбрав наиболее безопасный, оптимальный и результативный. Для этого сравните все варианты. Задумайтесь, к каким последствиям эти действия могут привести? Какие риски и угрозы могут нести? Конечно, любой прогноз неточен. Однако в большинстве случаев он помогает избежать явных ошибок. Обращайтесь не только к своему опыту, но и к чужому. Я люблю повторять: «Дураки учатся на своих ошибках, а умные — на чужих».
Вам поможет классическая технология — SWOT-анализ. Метод простой и действенный. Анализируя каждый из вариантов решения проблемы, последовательно задавайте себе четыре вопроса:
- В чем сильные стороны этого варианта решения?
- В чем слабые стороны этого варианта решения?
- Какие есть возможности в реализации этого варианта решения?
- Какие есть угрозы и опасности в реализации этого варианта решения?
Оценив все идеи, выберите лучшую. Не всегда доверяйте интуиции. Часто нам нравится какой-то путь, но его выбор абсолютно ничем не обоснован. Не тыкайте пальцем в небо, надеясь на авось или удачу. Визуализируйте и систематизируйте все возможные варианты. Используйте таблицы для сравнения их эффективности. Любая визуализация (стикеры на стене, блок-схемы, древовидные системы, майнд-мепинг и пр.) раскладывает все по полочкам и помогает «увидеть» оптимальное решение.
Шаг 5 — Разработка плана действий
Когда вариант решения выбран, начинайте рационально и скурпулезно планировать. Составьте конкретную пошаговую инструкцию действия, оставив пространство для маневра. Есть еще и шестой, негласный, пункт этого алгоритма — сама по себе реализация плана. Здесь понадобятся терпение и дисциплина. В своей практике я видел много тактиков и стратегов, которые могли решать конкретные бизнес-задачи только в теории, создавая сложные прогнозы и системы оценок, апеллируя разными бенчмаркингами и статистиками. Человек, который действительно
решает проблемы — не теоретик. Он практик. Он берет и начинает делать. Ведь любая идея требует
конкретной реализации.
Немного философии на финал
Для большинства действительно крупных проблем нет окончательных решений. Человечество вечно будет бороться с голодом и болезнями, несправедливостью и злоупотреблением власти, природными катастрофами и военными конфликтами. Каждый раз ищите актуальное и наиболее оптимальное решение с учетом всех обстоятельств. Каждый раз, находя решение, не забывайте свой прошлый опыт. К сожалению, мы редко оглядываемся на свой и чужой опыт, и часто это является ключевой проблемой.
Предложенный мной алгоритм поначалу может показаться многим очевидным. Но давайте честно признаемся: когда мы сталкиваемся в реальной жизни со сложной проблемой, то чаще всего поддаемся панике вместо того, чтобы действовать системно и последовательно. Критически мыслящий человек не станет опираться на первое решение, которое пришло ему в голову, действовать по шаблону или спонтанно и иррационально. Он всегда будет мыслить гибко, пытаясь найти самые верные и оптимальные решения. Пусть и не самые очевидные. А в поиске этих самых нешаблонных и творческих решений поможет креативное мышление.
Источник: РБК PRO
Алгоритм решения проблем — Психология PRO
Личная эффективность
Опубликовано Автор: Игорь Саторин / 10 комментариев
Есть два распространенных подхода к решению проблем — взрослый и детский.
Трезвомыслящий человек не спрашивает себя сразу: «как бы мне поудобней проблему решить?». Он сначала спрашивает себя так: «а какие, вообще, у меня есть варианты?». А среди них уже самый удобный выбирает.
Капризы, жалобы, поиск справедливости, «правильного» и «должного» — это подход детский, идеалистичный. Исследование реальных вариантов — подход зрелый, реалистичный.
Что такое проблема?
Проблема — это тревожная неопределенность, когда провисает неприятная ситуация. Ум как бы заедает на вопросе «что делать?», и он мечется словно в тумане между землей и небом в поисках опоры, чтобы остановиться и успокоиться.
А найти устойчивый привал определенности мешает замутненный взор на альтернативы: либо, вообще, неясно, каков выбор, либо он представляется смутно. Неизвестность, как принято считать, тревожит — и это правда. А если в ней дополнительно угадываются мрачные нотки, то смутные опасения нарастают.
Задача психолога в такой ситуации — помочь клиенту высунуть голову из марева механического мышления, и увидеть, на что можно рассчитывать: опознать варианты фантастические — выбросить их, и навести фокус на реальный выбор.
Изначально никаких проблем в объективной реальности нет. Есть ситуации. Все проблемы — психологические, субъективные. Даже если человек заблудился в лесу, поранился и отключается от потери крови — это необязательно станет ему проблемой.
Проблемы обнаруживает повсюду спящий в мутных грезах ум. Банально приборка в квартире может показаться необходимостью погрузиться в тягомотное, вымученное «нечто» — разыгранную для себя же миниатюрную драму.
А если этот смутный фон конкретизировать, четко опознать опорные точки нежеланного процесса, тогда тревога рассеется и ум без капризов определится: прибраться, или отложить.
Если определиться не получается, значит что-то упущено — облачка тревожных предвкушений продолжают фонить.
Бастионы эго
Пример. Распространенная ситуация: жена и муж обязывают друг друга оказывать конкретные знаки внимания и любви, но как-то не получается… — внешняя маркировка чувств одного супруга не отвечает запросам второго. Что происходит? То же самое: люди закрывают глаза на свой реальный выбор, потому что прицеливаются на удобный. В прошлых статьях на progressman.ru я попытался донести тщетность таких расчетов.
А что если текущие отношения — это лучшее, на что сегодня можно с человеком рассчитывать? Разве реально улучшить отношения требованиями? Скорей, чем больше требуешь, тем меньше получаешь. Требования убивают отношения.
Когда люди в поисках справедливости начинают бодаться, сталкиваются их неприкосновенные оборонные бастионы эго. Разве можно всерьез рассчитывать, что человек так просто сдаст свою сегодняшнюю «правду», станет «справедливым и адекватным»? А что если он изначально обыкновенный непроходимый болван? Обязан ли он меняться?
Когда мы закрываем глаза на реальные возможности людей, и слепо от них что-то требуем, то по сути призываем их надорваться в попытках совершить невозможное.
Любые конфликты — все та же проблемная неопределенность, когда замутненный эмоциями ум уклоняется от признания реального выбора, и рассчитывает на фантастику.
В одной из статей я уже говорил: невротик задается вопросом «чего я заслуживаю?», здоровая личность — вопросом «какие у меня есть возможности?».
Когда наилучшая актуальная возможность признана, приходит смирение с потерями и успокоение. Потерянные альтернативы — плата за решение проблемы и выход из неопределенности.
Алгоритм
Один из верных способов повиснуть в неопределенности — это попытки по школьной привычке совершить так называемый «правильный» выбор: указать себе направление и силком туда двигаться. А что если этого направления в реальности просто нет? Безвыходные ситуации возникают, когда нереалистичные варианты кажутся правильными и обязательными.
Правильный выбор существует только в отношении реального результата. Для приготовления чая будет правильным залить кипятком заварку. Это конкретная закономерность. А выбор «вообще» всегда совершается в направлении максимального душевного комфорта. И другим правилам не подчиняется.
Даже совесть подвинется, если ее требования напрягают сильней ее же обвиняющих угрызений. Как бы «правильно» ни хотелось поступать по моральным меркам, всегда поступаешь «правильно» по меркам личным — то есть так, как для себя и хотелось.
Каждый миг искренне реализуется единственный возможный вариант себя. Иного текущий опыт не позволяет. Таков естественный поток видимых и скрытых тенденций индивидуальности.
В каждого заложен уникальный путь к личному счастью. Поэтому у каждого к нему и свой вкус — этот интимный ориентир — единственный надежный индикатор верного направления.
Поэтому психолог — не морализирует, не указывает, как поступать, ничего не советует, а помогает клиенту перестать капризничать, и признать реальные варианты выхода из неопределенности. Дальше клиент полагается на собственный вкус — личный индекс счастья, и решает сам, что выбрать.
Алгоритм решения проблем:
1. уточнить проблему
2. опознать реальные варианты взаимодействия с ней
3. выбрать самый привлекательный
© Игорь Саторин
Другие статьи по теме:
- Эмоции – реальный источник проблем
- Решение проблем
- Самообман
выбор, Продуктивность и мотивация, Психотерапия
Чтобы прояснить свою уникальную ситуацию основательней, вы можете пройти со мной консультацию по скайпу. Условия и подробности по этой ссылке.Благодарю тех, кто не ограничился формальными «спасибо», а внес реальный вклад в развитие progressman.ru!
Рассказать друзьям:
Progressman.ru на Youtube:
Как использовать алгоритмы для решения проблем?
Алгоритм — это процесс или набор правил, которым необходимо следовать для выполнения конкретной задачи. Это в основном пошаговая процедура для выполнения любой задачи. Все задачи выполняются по определенному алгоритму, от приготовления чашки чая до создания масштабируемого программного обеспечения. Это способ разделить задачу на несколько частей. Если мы нарисуем алгоритм выполнения задачи, то задачу будет легче выполнить.
Алгоритм используется для,
- Разработать основу для обучения компьютеров.
- Введены обозначения основных функций для выполнения основных задач.
- Для определения и описания большой проблемы небольшими частями, чтобы ее было очень легко выполнить.
Характеристики алгоритма
- Алгоритм должен быть четко определен.
- Алгоритм должен выдавать хотя бы один результат.
- Алгоритм должен иметь ноль или более входных данных.
- Алгоритм должен быть выполнен и завершен за конечное число шагов.
- Алгоритм должен быть простым и простым в исполнении.
- Каждый шаг начинается с определенного отступа, например, «Шаг-1»,
- Должен быть «Начало» в качестве первого шага и «Конец» в качестве последнего шага алгоритма.
Возьмем, к примеру, приготовить чашку чая,
Шаг 1: Запуск
Шаг 2: Набери немного воды в миске.
Шаг 3: Поставьте воду на газовую горелку .
Шаг 4: Включите газовую горелку
Шаг 5: Подождите некоторое время, пока вода не закипит.
Шаг 6: Добавьте в воду несколько чайных листьев в соответствии с требованиями.
Шаг 7: Затем снова подождите некоторое время, пока вода не станет цвета чая.
Шаг 8: Затем добавьте немного сахара по вкусу.
Шаг 9: Снова подождите некоторое время, пока сахар не растает.
Шаг 10: Выключите газовую горелку и подавайте чай в чашках с печеньем.
Шаг 11: Конец
Вот алгоритм приготовления чашки чая. То же самое и с задачами по информатике.
Есть несколько основных шагов для создания алгоритма:
- Старт – Запуск алгоритма
- Вход — Принять входные данные для значений, при которых будет выполняться алгоритм.
- Условия — Выполните некоторые условия на входах, чтобы получить желаемый результат.
- Вывод – Печать выводов.
- Конец – Завершить выполнение.
Давайте рассмотрим несколько примеров алгоритмов для задач информатики.
Пример 1. Поменять местами два числа с третьей переменной
Шаг 1: Запуск
Шаг 2: Возьмите 2 числа в качестве входных данных.
Шаг 3: Объявите другую переменную как «temp».
Шаг 4: Сохраните первую переменную в «temp».
Шаг 5: Сохраните вторую переменную в первой переменной.
Шаг 6: Сохраните переменную «temp» во второй переменной.
Шаг 7: Распечатайте первую и вторую переменные.
Шаг 8: Конец
Пример 2. Найдите площадь прямоугольника
Шаг 1: Запустите
Шаг 2: В качестве входных данных возьмите высоту и ширину прямоугольника.
Шаг 3: Объявить переменную как «площадь»
Шаг 4: Умножить высоту и ширину )
Шаг 6: Напечатать «площадь»;
Шаг 7: Конец
Пример 3. Найдите наибольшее из 3 чисел.
Шаг 1: Запустить
Шаг 2: В качестве входных данных взять 3 числа, скажем A, B и C.
Шаг 3: Проверить, если (A>B и A>C3)
Шаг 4: Тогда A больше
Шаг 5: Распечатать A
Шаг 6 : Иначе
Шаг 7: Проверить, если (B>A и B>C)
Шаг 8: , затем B превышает
Шаг 9: Печать B
Шаг 10: ELS
Преимущества алгоритма
- Алгоритм использует определенную процедуру.
- Это легко понять, потому что это пошаговое определение.
- Алгоритм легко отладить, если произойдет какая-либо ошибка.
- Не зависит ни от какого языка программирования.
- Программисту легче преобразовать ее в настоящую программу, потому что алгоритм делит задачу на более мелкие части.
Недостатки алгоритмов
- Алгоритм требует много времени, для разных алгоритмов существует определенная временная сложность.
- Большие задачи трудно решать в алгоритмах, потому что временная сложность может быть выше, поэтому программисты должны найти хороший эффективный способ решения этой задачи.
- Циклы и ветвления трудно определить в алгоритмах.
Стратегии решения проблем с алгоритмами — Сообщество разработчиков 👩💻👨💻
Головоломки с алгоритмами — это, к сожалению, распространенный способ отсеять кандидатов в процессе подачи заявок. Однако, когда вы не беспокоитесь о поиске работы, это на самом деле очень весело, как кроссворды для программистов.
При их решении возникают уникальные проблемы, с которыми вы не столкнетесь при запуске приложения Yet Another Crud, и вы познакомитесь с концепциями, с которыми вы, возможно, еще не знакомы. Практика алгоритмических задач улучшит ваши более широкие способности решения проблем, а также укрепит процесс решения проблем, который будет более полезным в целом.
Как и в случае с другими типами головоломок, существуют стратегии, которые дают вам раннее понимание проблемы и способ разбить ее на более мелкие, более доступные части. В настоящей головоломке вы можете рассортировать кусочки по согласованным группам схожих цветов или характеристик, найти очевидные совпадения и расти дальше.
С сапером вы можете начать со случайного щелчка, а затем перемещаться по открытым краям, отмечая очевидные мины и обнажая очевидные чистые области, щелкая случайным образом еще раз только тогда, когда вы исчерпали все возможности. Несмотря на то, что существуют стратегии для работы с подобными типами алгоритмов, я бы порекомендовал вам начать с более широкой стратегии решения проблем, которую вы принимаете как общую привычку, а не только когда вы шлифуете LeetCode в качестве подготовки к собеседованию.
Вместо того, чтобы углубляться в проблему, подойдите к проблеме поэтапно:
Подумайте:
- Проанализируйте проблему
- Переформулируйте проблему
- Запишите примеры ввода и вывода
- Разбейте проблему на составные части
- Обрисовать решение в псевдокоде
- Пройдитесь по данным вашего примера с вашим псевдокодом
Выполнить
- Закодировать
- Проверьте свое решение на своих примерах
- Рефакторинг
(Если вы знакомы с этим подходом, перейдите к шаблонам алгоритмов)
Проанализируйте проблему
Возможно, вас осенило, когда вы впервые увидели проблему. Как правило, это ваш ум, соединяющийся с каким-то предыдущим опытом. Держитесь за это понимание! Тем не менее, вы все равно должны потратить некоторое время на изучение проблемы, особенно на то, как ваше понимание отличается от фактического вопроса.
Любая хорошо написанная головоломка содержит компоненты, необходимые для решения задачи, содержащейся в одном-двух предложениях. Однако то, что вы читаете задачу, не означает, что вы ее понимаете. И если вы не понимаете проблемы, вы будете бесцельно спотыкаться или решать то, что, как вы предполагали, было проблемой.
Найдите ключевые слова, которые определяют форму задачи.
Определите ввод.
Определите желаемый результат.
Определите критически важные ключевые слова и фразы.Например, LeetCode #26
Учитывая [отсортированный] [массив] nums, [удалить дубликаты] [на месте], чтобы каждый элемент появлялся только один раз, и [возвратить новую длину].
Не выделяйте дополнительное пространство для другого массива, это необходимо сделать, изменив входной массив на месте с [O(1) дополнительной памяти].
Ввод:
- массив. Итак, мы знаем, что, вероятно, собираемся сделать какую-то итерацию.
- массив чисел. Это больше подразумевается, чем конкретно указано, и на самом деле не так важно, как мы можем использовать тот же набор условных выражений.
Возврат:
- длина измененного массива
Побочный эффект- : модифицированный массив
Критические слова и фразы:
- отсортировано: повторяющиеся элементы будут рядом друг с другом
- удалить… дубликаты
- на месте: сам массив должен быть деструктивно изменен. Это ограничение определяет, какие методы массива мы можем использовать.
- Дополнительная память O(1): мы ограничены пространственной сложностью O(1), что позволяет нам определять переменные, но не создавать копию массива.
Переформулируйте проблему
Теперь, своими словами, перефразируйте это так, чтобы оно имело для нас смысл. Если вы находитесь на собеседовании, вы можете пересказать интервьюеру, как для того, чтобы запомнить его, так и для того, чтобы убедиться, что вы правильно его услышали и поняли.
Пересчитано:
При наличии отсортированного массива чисел, переданного по ссылке, деструктивно изменить исходный массив на месте, удалив дубликаты, чтобы каждое значение появлялось только один раз. Возвращает длину измененного массива.
Запишите пример входных данных и ожидаемых результатов
Все, что мы делаем, это сопоставляем входы с выходами. Задача состоит в том, чтобы выяснить, как добраться из A в B, однако сначала нам нужно установить, что такое A и B . Даже если вам дали тест-кейсы, напишите свои. Глядя на что-то, не создается почти такого же понимания, как если бы вы делали это для себя.
Это также прекрасное время, чтобы изучить свое понимание проблемы и найти особенности, которые могут сбить с толку наивное решение. Это включает в себя крайние случаи, такие как пустые входные данные, массив, заполненный дубликатами одного и того же значения, массивный набор данных и т. д. Нам не нужно беспокоиться ни о чем, кроме ограничений задачи 9.0003
Запишите не менее 3 примеров:
[] -> [], возврат 0 [1] -> [1], вернуть 1 [1, 1, 2, 3, 4, 4, 4, 5] -> [1, 2, 3, 4, 5], вернуть 5 [1, 1, 1, 1, 1] -> [1], вернуть 1Учитывая входные данные, достаточно ли у вас информации для сопоставления с результатом? Если вы этого не сделаете, сделайте шаг назад и продолжите изучение проблемы, прежде чем продолжить. Если вы проводите собеседование, не стесняйтесь просить разъяснений.
Ищите простой и последовательный процесс, который можно применять независимо от ценности для достижения результата. Если вы получите запутанную серию шагов и исключений, вы, вероятно, зашли слишком далеко и пропустили более простое решение.
Разбейте проблему на мелкие части
Начиная с самого простого примера, просто сведите задачу к основной головоломке и развивайте ее. В данном случае это массив из трех элементов, два из которых дублируются, например.
[1, 1, 2]
. Сведение проблемы к такому небольшому случаю делает ее более доступной и проясняет первый шаг, который вам нужно сделать. Ваша задача состоит в том, чтобы разработать процедуру, которая решает этот простой случай и , справедливый для всех других случаев в наборе задач.Итак, мы знаем, что нам нужно сделать пару вещей:
- Перебрать массив
- Следим за тем, где в массиве мы находимся
- Проверить соседние значения на равенство
- Деструктивно удалить все повторяющиеся значения после первого вхождения
- Получить окончательную длину массива и вернуть ее
Это относительно простой пример задачи, однако в ней скрывается подвох : многие итерационные методы плохо работают с удалением элементов из массива , в то время как вы перебираете массив, потому что значения индекса меняются. Вы можете в конечном итоге пропустить дубликат, потому что указатель увеличился над ним.
Эта ошибка указывает на то, что мы хотим использовать подход, который дает нам явное управление итерацией.
В более сложной задаче мы могли бы рассматривать некоторые или все эти компоненты как вспомогательные функции, что позволит нам написать ясное и краткое решение, а также проверить правильность каждой из наших подчастей по отдельности.
Псевдокод решения
Если мы четко поняли проблему, определили основные задачи и, надеюсь, заметили недостатки в наших собственных предположениях и любые ошибки, мы пишем понятное для человека описание того, каким будет наш подход. Надеюсь, когда мы это сделаем, мы сможем аккуратно преобразовать его в работающий код.
То, как вы пишете псевдокод, зависит от вас. Ваши обозначения не обязательно должны быть идеально написаны и грамматически правильны. Это может быть жестовая комбинация кода и слов, предназначенная для передачи значения. Ваш псевдокод предоставит содержательную дорожную карту, к которой вы сможете вернуться, если обнаружите, что глубоко заблудились в деталях реализации, поэтому убедитесь, что вы записали достаточно, чтобы быть полезными позже.
Если вы проводите собеседование, это отличная возможность рассказать интервьюеру о ваших намерениях. И если у вас мало времени, у вас по крайней мере будет что-то на доске, демонстрирующее ваш подход к решению проблем.
Рекомендации:
- начать с сигнатуры функции:
removeDuplicates :: (массив) -> номер
- при использовании интерактивной доски оставьте достаточно места для написания фактического кода
- , если вы используете IDE, пишите комментарии и храните их отдельно от кода, чтобы вы могли ссылаться на них позже.
- напишите это как серию шагов и используйте маркеры
Поскольку мы ищем дубликаты, это означает, что нам нужно выполнить сравнение. Мы можем смотреть вперед на нашу текущую позицию в массиве или мы можем смотреть назад.
// удалить дубликаты :: (массив) -> номер // если массив пуст или содержит 1 элемент, вернуть длину массива и выйти // итерация по массиву // сравниваем каждый элемент со следующим элементом // // повторяем до false: // если следующий элемент совпадает с текущим элементом // удаляем следующий элемент // // переходим к следующему элементу массива // остановимся, как только будет достигнут предпоследний элемент // возвращаем длину массиваМы начинаем с выхода, если размер нашего массива составляет всего 0 или 1 элемент, отчасти потому, что эти случаи удовлетворяют условиям задачи: нет возможных дубликатов, а отчасти потому, что они сломают наш код, если мы попытаемся сравнить первое значение со вторым, которого не существует.
Мы также устанавливаем условие выхода из итерации, и, поскольку мы будем использовать просмотр вперед, мы обязательно остановим до того, как мы достигнем последнего элемента.
Потому что мы не перемещаем позицию указателя до после мы разобрались с любыми дубликатами, мы должны быть свободны от проблемы смещения индексов.
Пройдитесь по образцу данных
Уделите немного времени и мысленно пропустите некоторые образцы данных через наш псевдокод:
[] -> [], return 0 [1] -> [1], вернуть 1 [1, 1, 2, 3, 4, 4, 4, 5] -> [1, 2, 3, 4, 5], вернуть 5 [1, 1, 1, 1, 1] -> [1], вернуть 1Мы что-то упустили?
Может возникнуть проблема с последним примером:
[1, 1, 1, 1, 1]
. Что произойдет, если мы удалим все дубликаты, а затем попытаемся перейти к следующему элементу в нашем массиве, не проверяя, есть ли они?Мы хотим убедиться, что наше конечное условие улавливает любые изменения длины массива.
Код это
Пора резине встретить дорогу. Здесь у вас есть все предположения, о которых вы даже не подозревали, что они вернулись, чтобы преследовать вас. Чем лучше вы смогли спланировать, тем меньше их будет.
функция удаления дубликатов (обр) { если (arr.length < 2) вернуть arr.length обратная длина приб. }Лично мне нравится сначала вводить возвращаемые значения. Таким образом, я ясно понимаю, какова моя цель, и я также зафиксировал первый случай пустых или одноэлементных массивов.
функция удаления дубликатов (обр) { если (arr.length < 2) вернуть arr.length for(пусть i = 0; i < arr.length; arr++) {} обратная длина приб. }Да, мы используем стандартный цикл for. Я предпочитаю не использовать их, если есть более подходящий или более чистый синтаксис, но для этой конкретной проблемы нам нужна возможность контролировать нашу итерацию.
функция удаления дубликатов (обр) { если (arr.length < 2) вернуть arr. length for(пусть i = 0; i < arr.length; i++) { в то время как (arr[i + 1] && arr[i] === arr[i + 1]) arr.splice(i + 1, 1) } обратная длина приб. }И это работает из коробки, кроме:
removeDuplicates([0,0,1,1,1,2,2,3,3,4]) //> 6, должно быть 5Оказывается, проверка существования, которую я пробрался в цикле while, разрешается как ложная, если значение массива равно
0
. Спасибо JavaScript! Итак, давайте просто переработаем это очень быстро и посмотрим назад, а не вперед, что также немного очистит код:function removeDuplicates(arr) { если (arr.length < 2) вернуть arr.length for(пусть i = 0; i < arr.length; i++) { в то время как (arr[i] === arr[i - 1]) arr.splice(i, 1) } обратная длина приб. }И это проходит. Это эффективное решение для памяти, мы определили только 1 переменную, кроме ссылки на массив. И это средняя скорость, которую мы могли бы улучшить.
Но в основном это был простой пример процесса:
- Анализ
- Переформулировать
- Примеры записи
- Разберитесь с мелкими проблемами
- Контур в псевдокоде
- Шаг по псевдокоду с примерами
- Код
- Тест
- Рефакторинг
Помимо определенных структур данных и алгоритмов, которые имеют известные и довольно стандартизированные подходы, проблемы с алгоритмами, как правило, делятся на категории, которые предполагают аналогичные подходы к решению. Изучение этих подходов дает вам точку опоры в проблеме.
Несколько указателей
Когда мы впервые учимся перебирать коллекцию, обычно массив, мы делаем это с помощью одного указателя с индексом, идущим от наименьшего значения к наибольшему. Это работает для некоторых операций и просто для рассмотрения и кода. Однако для задач, связанных со сравнением нескольких элементов, особенно тех, где важна их позиция в коллекции, поиск соответствующего значения с помощью одного указателя требует повторения массива по крайней мере один раз для каждого значения, O(n 2) операция.
Если вместо этого мы используем несколько множественных точек, мы потенциально можем сократить вычисление до операции O(n).
Существуют две общие стратегии: два указателя и скользящее окно
Два указателя
Почему бы не начать с обоих концов и не продвигаться вперед? Или начните со значения или пары значений и расширяйтесь наружу. Это отличный подход для поиска самой большой последовательности в коллекции.
Поскольку вы работаете с двумя точками, вам необходимо определить правило, чтобы гарантировать, что они не пересекаются друг с другом.
// Временная сложность O(n) // Пространственная сложность O(1) функция sumZero(arr) { пусть слева = 0; пусть право = массив.длина - 1; в то время как (слева < справа) { пусть сумма = обр [слева] + обр [право]; если (сумма === 0) вернуть [обр [слева], обр [право]]; иначе если (сумма > 0) право--; иначе осталось++; } }Раздвижное окно
Вместо размещения двух точек на внешних границах мы можем пройтись по нашему массиву, последовательно перемещая два указателя параллельно. Ширина нашего окна может увеличиваться или уменьшаться в зависимости от набора задач, но оно продолжает перемещаться по коллекции, захватывая моментальный снимок любой последовательности, которая лучше всего соответствует желаемому результату.
функция maxSubarraySum(массив, n) { если (array.length < n) n = array. length; пусть сумма = 0; для (пусть i = 0; i < n; i++) { сумма = сумма + массив [i]; } пусть maxSum = сумма; // сдвиг окна по массиву for (пусть я = n; я < array.length; я ++) { сумма = сумма + массив [i] - массив [i - n]; если (сумма > maxSum) maxSum = сумма; } вернуть максимальную сумму; }Разделяй и властвуй
Разделяй и властвуй часто используется рекурсивный подход: применение одного и того же правила для разделения коллекции до тех пор, пока вы не разбьете ее на мельчайшие компоненты и не определите ответ.
Двоичный поиск и сортировка слиянием являются прекрасными примерами рекурсивного подразделения, ведущего к решению.
O(1) Поиск: Объект/Словарь/Хэш
Хешированный ключ: Хранилища значений, называемые объектами, словарями или хэшами в зависимости от вашего языка кодирования, являются невероятно полезными инструментами для хранения информации при подсчете частоты, проверке на наличие дубликатов или дополнении ответа. Как там
Вы можете сохранить значение, или вместо этого вы можете сохранить значение, которое вы ищете. Например, при поиске пар с нулевой суммой в массиве мы можем сохранить дополнение, а не само значение.
Ресурсы:
Основы алгоритмического решения задач (видео)
Алгоритмическое решение задач для программистов
10 лучших алгоритмов в вопросах на собеседовании
Улучшение ваших навыков работы с алгоритмами и структурами данныхЧто такое алгоритм решения проблем?, шаги, представление
Алгоритм решения проблем ?
Компьютеры используются для решения различных повседневных задач, поэтому решение проблем является важным навыком, которым должен владеть студент, изучающий информатику. Уместно отметить, что компьютеры сами по себе не могут решить проблему. Для решения проблемы мы должны предоставить точные пошаговые инструкции.
Алгоритм решения проблемСодержание
- 1 Что такое алгоритм решения проблем?
- 2 Definition of Problem Solving Algorithm
- 3 Steps for Problem Solving
- 3. 1 Analysing the Problem
- 3.2 Developing an Algorithm
- 3.3 Coding
- 3.4 Testing and Debugging
- 4 Representation of Algorithms
- 4.1 Flowchart
- 4.1.1 Преимущества блок-схем:
- 4.1.2 Различия между алгоритмом и блок-схемой
- 4.2 Псевдокод
- 4.2.1 Преимущества псевдокода
Таким образом, успех компьютера в решении задачи зависит от того, насколько правильно и точно мы определим задачу, спроектируем решение (алгоритм) и реализовать решение (программу) с помощью языка программирования.
Таким образом, решение проблем представляет собой процесс выявления проблемы, разработки алгоритма для выявленной проблемы и, наконец, реализации алгоритма для разработки компьютерной программы.
Определение алгоритма решения задач
Ниже приведены некоторые простые определения алгоритма решения задач:
Алгоритмы – это решения вычислительных задач. Они определяют метод, который использует входные данные для задачи, чтобы получить правильный результат. Вычислительная задача может иметь множество решений.
Алгоритм определяется как пошаговая процедура, предназначенная для выполнения операции, которая при правильном выполнении приведет к желаемому результату.
Алгоритмы имеют определенное начало и определенный конец, а также конечное число шагов. Хороший алгоритм, который является точным, уникальным и конечным, получает ввод и производит вывод.
Набор последовательных шагов, обычно написанных на обычном языке для решения данной проблемы, называется алгоритмом.
Этапы решения проблем
Когда проблемы просты и просты, мы можем легко найти решение. Но сложная проблема требует методического подхода для поиска правильного решения. Другими словами, мы должны применять методы решения проблем.
Решение проблем начинается с точного определения проблемы и заканчивается полным рабочим решением с точки зрения программы или программного обеспечения. Ключевые шаги, необходимые для решения проблемы с помощью компьютера.
Например: Предположим, во время движения автомобиль начинает издавать странный шум. Мы можем не знать, как решить проблему сразу. Во-первых, нам нужно определить, откуда исходит шум? В случае, если проблема не может быть решена нами, тогда нам необходимо доставить автомобиль к механику.
Механик проанализирует проблему, чтобы определить источник шума, составит план предстоящих работ и, наконец, отремонтирует автомобиль, чтобы устранить шум. Из примера ясно, что поиск решения проблемы может состоять из нескольких шагов.
Ниже приведены шаги для решения проблемы:
Шаги для решения проблемы
- Анализ проблемы
- Разработка алгоритма
- Кодирование
- Тестирование и отладка
Анализ проблемы
Важно четко понять проблему, прежде чем мы начнем искать для нее решение. Если нам не ясно, что нужно решить, мы можем закончить тем, что разработаем программу, которая может не решить нашу цель.
Таким образом, нам необходимо внимательно прочитать и проанализировать постановку задачи, чтобы перечислить основные компоненты проблемы и определить основные функции, которыми должно обладать наше решение. Анализируя проблему, мы могли бы выяснить, какие входные данные должна принимать наша программа и какие выходные данные она должна производить.
Разработка алгоритма
Прежде чем писать программный код для данной задачи, необходимо найти решение. Решение представляется на естественном языке и называется алгоритмом. Мы можем представить себе алгоритм как очень хорошо написанный рецепт блюда с четко определенными шагами, следуя которым, можно приготовить блюдо.
Мы начинаем с предварительного плана решения и продолжаем совершенствовать алгоритм, пока он не сможет охватить все аспекты желаемого решения. Для данной задачи возможно несколько алгоритмов, и мы должны выбрать наиболее подходящее решение.
Кодирование
После окончательной доработки алгоритма нам необходимо преобразовать алгоритм в формат, понятный компьютеру, чтобы сгенерировать желаемое решение. Для написания программы могут использоваться различные языки программирования высокого уровня. Не менее важно записывать детали выполненных процедур кодирования и документировать решение. Это полезно при повторном посещении программ на более позднем этапе.
Тестирование и отладка
Созданная программа должна быть протестирована на различных параметрах. Программа должна соответствовать требованиям пользователя. Он должен ответить в течение ожидаемого времени. Он должен генерировать правильный вывод для всех возможных входных данных. При наличии синтаксических ошибок вывод не будет получен. В случае, если сгенерированный вывод неверен, то следует проверить программу на наличие логических ошибок, если таковые имеются.
Индустрия программного обеспечения использует стандартные методы тестирования, такие как модульное или компонентное тестирование, интеграционное тестирование, системное тестирование и приемочное тестирование при разработке сложных приложений. Это делается для того, чтобы программное обеспечение соответствовало всем деловым и техническим требованиям и работало должным образом.
Ошибки или дефекты, обнаруженные на этапах тестирования, отлаживаются или исправляются, и программа снова тестируется. Это продолжается до тех пор, пока все ошибки не будут удалены из программы. После того, как программное приложение было разработано, протестировано и доставлено пользователю, все еще могут возникать проблемы с точки зрения функционирования, которые время от времени необходимо решать.
Таким образом, обслуживание решения включает в себя устранение проблем, с которыми сталкивается пользователь, ответы на запросы пользователя и даже обслуживание запроса на добавление или изменение функций.
Представление алгоритмов
Используя свои навыки алгоритмического мышления, разработчики программного обеспечения или программисты анализируют проблему и определяют логические шаги, которые необходимо выполнить для достижения решения. После определения шагов необходимо записать эти шаги вместе с требуемыми входными данными и желаемыми выходными данными.
Существует два распространенных метода представления алгоритма — блок-схема и псевдокод. Любой из методов можно использовать для представления алгоритма, учитывая следующее:
- Он демонстрирует логику решения проблемы, исключая какие-либо детали реализации.
- Он ясно показывает поток управления во время выполнения программы.
Блок-схема
Блок-схема — это визуальное представление алгоритма. Блок-схема представляет собой диаграмму, состоящую из прямоугольников, ромбов и других фигур, соединенных стрелками. Каждая фигура представляет собой шаг процесса решения, а стрелка представляет порядок или связь между шагами.
Блок-схема представляет собой пошаговое схематическое представление логических путей решения данной проблемы. Или Блок-схема — это визуальное или графическое представление алгоритма.
Блок-схемы являются графическим изображением методов, используемых для решения данной проблемы, и очень помогают анализировать проблему и планировать ее решение систематическим и упорядоченным образом. Блок-схема при переводе на соответствующий компьютерный язык приводит к полной программе.
Преимущества блок-схем:
- Блок-схема показывает логику проблемы, отображаемую в графическом виде, что облегчает проверку алгоритма
- Блок-схема является хорошим средством общения с другими пользователями. Это также компактное средство записи алгоритма решения задачи.
- Блок-схема позволяет решателю проблемы разбить проблему на части. Эти части могут быть соединены, чтобы сделать основную диаграмму.
- Блок-схема представляет собой постоянную запись решения, к которой можно обратиться позднее.
Различия между алгоритмом и блок-схемой
Серийный номер Алгоритм Блок-схема 1 Способ представления пошаговой логической процедуры решения задачи. Блок-схема — это схематическое представление алгоритма. Он построен с использованием различных типов блоков и символов. 2 Он содержит пошаговые описания на английском языке, каждый шаг представляет собой конкретную операцию, ведущую к решению проблемы. В блок-схеме используется ряд блоков и стрелок, каждый из которых представляет определенный шаг алгоритма. 3 Они особенно полезны при решении небольших задач. Они полезны для подробного представления сложных программ. 4 Для сложных программ алгоритмы оказываются неадекватными. Для сложных программ блок-схемы подходят. Псевдокод
Псевдокод не является ни алгоритмом, ни программой. Это абстрактная форма программы. Он состоит из английских операторов, которые выполняют определенные операции.